$ p="pineapple" ; echo $p
pineapple
$ (p="peach" ; echo $p)
peach
$ echo $p
pineapple
シェルが最後に初期化された後、なぜ桃を表示しないのですか?括弧はこの結果に影響しますか?
答え1
はい、これはBourneやcshなどのシェルで括弧が実行することです。bash
変更が制限されるサブシェル環境(サブプロセスブランチを含むほとんどのシェル)を導入します。
変数、オプション、エイリアス、関数、リダイレクト、現在の作業ディレクトリ、シグナル構成など、対応するサブシェル環境内のシェルの状態に対するすべての変更は、終了時に失われます(復元)。
実行に非常に便利ただ他の環境のいくつかのコマンド。
たとえば、
(cd /some/dir && cmd)
cmd
別のディレクトリで実行してください。
または、次のようになります。
(IFS=:; set -o noglob; ls -l -- $PATH)
1つの拡張に対してのみSplit + Glob演算子を調整します$PATH
。
サブシェル環境を導入せずにコマンドをグループ化するには、{
キーワード}
を使用します。
a=1
{ echo "I'm running in the main shell environemnt"; a=2;}
echo "$a"
(echo "I'm running in a subshell environment"; a=3)
echo "$a"
{
;
a 前後のスペースは、}
通常の文字で構成されるキーワードであり、これ(
は、)
サブシェルの構成に使用されるシェル構文の特殊文字であるためです(...)
。
また、これが(...)
サブシェル環境を導入する唯一の構成ではないことに注意してください。また(Bourne / Kornのようなシェルから):
- 任意の形式のコマンドの置換:
$(subshell)
または`subshell`
- プロセス置換:
<(subshell)
、、、>(subshell)
=(subshell)
- パイプラインコンポーネント:(
{ subshell; } | othercommand
AT&T kshまたはzshの最後のコンポーネントではありません) - 非同期コマンド:
{ subshell; } &
- 共同処理:
{ subshell; } |&
またはcoproc { subshell; }
POSIX シェル構文では、および{ ...; }
両方が(...)
呼び出されます。複合コマンド。どちらも機能に割り当てることができます。関数を次のように定義します。
func() (
...
)
変える
func() {
...
}
つまり、関数の本文は一度呼び出されるとサブシェル環境で実行されるのでスクリプトのように動作します (呼び出し側からすべての変数、エイリアス、関数、オプションなどを継承し続けるという点だけを除く)。
fish
シェルでは(...)
全く違うものです。これはコマンドの置き換えですが、いいえサブシェル環境を導入します。
fish> set a 1; echo $a (set a 2; echo $a) $a
1 2 2
ksh93 または mksh シェルのコマンド置換形式に似ており、${ ...; }
サブシェル環境を導入しません。