当前位置: 首页>>技术教程>>正文


在bash中,何时使用()与{}?

, ,

问题描述

我正在用bash学习shell脚本,我需要知道(...){...}之间的区别。在编写脚本时如何在两者之间进行选择?

最佳解决思路

如果希望命令列表的side-effects影响当前shell,请使用{...}如果要丢弃任何side-effects,请使用(...)

例如,如果我:我可能会使用子shell:

  • 想要为一些命令改变$IFS,但我不想为当前shell全局改变$IFS

  • cd在某处,但我不想为当前的shell更改$PWD

值得注意的是括号可以在函数定义中使用:

  • 正常用法:大括号:函数体在当前shell中执行;功能完成后,side-effects保留

    $ count_tmp() { cd /tmp; files=(*); echo "${#files[@]}"; }
    $ pwd; count_tmp; pwd
    /home/jackman
    11
    /tmp
    $ echo "${#files[@]}"
    11    
    
  • 不寻常的用法:括号:函数体在子shell中执行;子壳退出时,side-effects消失

    $ cd ; unset files
    $ count_tmp() (cd /tmp; files=(*); echo "${#files[@]}")
    $ pwd; count_tmp; pwd
    /home/jackman
    11
    /home/jackman
    $ echo "${#files[@]}"
    0
    

Documentation

次佳解决思路

来自官方bash documentation

()

( list ) 

Placing a list of commands between parentheses causes a subshell environment to be created, and each of the commands in list to be executed in that subshell. Since the list is executed in a subshell, variable assignments do not remain in effect after the subshell completes.

{}

{ list; } 

Placing a list of commands between curly braces causes the list to be executed in the current shell context. No subshell is created. The semicolon (or newline) following list is required.

第三种解决思路

‘{}’中的代码在当前线程/进程/环境中执行并保留更改,更简洁地说,代码在当前范围内运行。 ‘()’中的代码在bash的单独子进程内运行,该进程在执行后被丢弃。这个子进程通常被称为sub-shell,可以被认为是一个新的child-like范围。

作为一个例子考虑以下……

 ~ # { test_var=test }
 ~ # echo $test_var
 test
 ~ # ( test_var2=test2 )
 ~ # echo $test_var2

 ~ # 

请注意,在'{}’的第一个示例中,即使在关闭’}’之后,变量仍然设置,而在'()’的示例中,变量未设置在'()’的范围之外。

第四种思路

(...)用于在sub-shell中运行代码。使用的代码{...}将不会用于sub-shell。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/1268.html,未经允许,请勿转载。