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]
'{}'内のコードは、現在のスレッド/プロセス/環境で実行され、変更は保存されます。より簡潔に言うと、現在のスコープでコードが実行されます。
'()'のコードは、実行後に破棄されるbashの独立した子プロセスの中で実行されます。 この子プロセスはしばしばサブシェルと呼ばれ
サブシェルと呼ばれ、新しい、子供のようなスコープと考えることができます。
例として、次のようなものを考えてみましょう...
~ # { test_var=test }
~ # echo $test_var
test
~ # ( test_var2=test2 )
~ # echo $test_var2
~ #
最初の例で '{}' を使った場合、 '}' を閉じた後でも変数が設定されていますが、 '()' を使った例では '()' の範囲外では変数が設定されないことに注目してください。
(...)` はサブシェルでコードを実行するために使用されます。の間で使用されるコードは、サブシェルでは使用されません。