bashで()と{}はいつ使い分ける?

bashでシェルスクリプトを勉強しているのですが、 (...){...} の違いを知りたいのです。スクリプトを書くときにどのように選択するのでしょうか?

ソリューション

コマンドリストの副作用を 現在の シェルにも及ぼしたい場合は、{...} を使用します。 副作用を取り除きたい場合は、(...) を使ってください。

例えば、私は以下のような場合、サブシェルを使うかもしれません。

  • いくつかのコマンドで $IFS を変更したいが、現在のシェルのグローバルな $IFS は変更したくない。
  • 現在のシェルの $PWD を変更したくない。

括弧は関数定義の中で使用できることに注意する必要があります。

  • 通常の使用法: 中括弧: 関数本体は現在のシェルで実行される; 関数が完了した後も副作用は残る

      $ count_tmp() { cd /tmp; files=(*); echo "${#files[@]}"; } }.
      $ pwd; count_tmp; pwd
      /ホーム/ジャックマン
      11
      /tmp
      $ echo "${#files[@]}"
      11
  • 珍しい使い方:括弧:関数本体はサブシェルで実行され、サブシェルが終了すると副作用が消える

      $ cd ;ファイルの設定を解除
      $ count_tmp() (cd /tmp; files=(*); echo "${#files[@]}")
      $ pwd; count_tmp; pwd
      /home/jackman
      11
      /home/jackman
      $ echo "${#files[@]}"
      0

[ドキュメント][1]

解説 (5)

'{}'内のコードは、現在のスレッド/プロセス/環境で実行され、変更は保存されます。より簡潔に言うと、現在のスコープでコードが実行されます。
'()'のコードは、実行後に破棄されるbashの独立した子プロセスの中で実行されます。 この子プロセスはしばしばサブシェルと呼ばれ サブシェルと呼ばれ、新しい、子供のようなスコープと考えることができます。

例として、次のようなものを考えてみましょう...

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

 ~ # 

最初の例で '{}&#39 を使った場合、 '}' を閉じた後でも変数が設定されていますが、 '()' を使った例では '()' の範囲外では変数が設定されないことに注目してください。

解説 (0)

(...)` はサブシェルでコードを実行するために使用されます。の間で使用されるコードは、サブシェルでは使用されません。

解説 (0)