2016-01-14 28 views
5

私は2つの間で混乱しています。

$ BASH_SUBSHELL内部変数はサブシェルのネストレベルを示しますが、$ SHLVL変数はサブシェル内で変更を示しません。

正確にはどういう意味ですか?別のシェル内でシェルを開くと、$ SHLVLの値が増えます。それはサブシェルではありませんか?

答えて

7

いいえ、手動で(/bin/shまたは/bin/bashなどを経由して)新しいシェルを実行するとこの文脈ではサブシェルではありません。

サブシェルは、シェルが新しいシェルインスタンスを生成して、それ自身でを処理するときです。

使用すると、Command Substitution(つまり$(command))はサブシェルです(古いバックティックの呼び出しと同様)。

pipeline(つまりecho '5.1+5.3' | bc -l)を使用すると、パイプラインの各コンポーネントにサブシェルが作成されます。

Process Substitution(つまり<(command))を使用すると、サブシェルが作成されます。

Grouping commands(つまり(declare a=5; echo $a))はサブシェルを作成します。

the background(つまりsleep 1 &)でコマンドを実行すると、サブシェルが作成されます。

他にもあるかもしれませんが、一般的なケースです。

テスト、これは簡単です:

$ printf "Outside: $BASH_SUBSHELL , $SHLVL\nInside: $(echo $BASH_SUBSHELL , $SHLVL)\n" 
Outside: 0 , 1 
Inside: 1 , 1 
$ (printf "Outside: $BASH_SUBSHELL , $SHLVL\nInside: $(echo $BASH_SUBSHELL , $SHLVL)\n") 
Outside: 1 , 1 
Inside: 2 , 1 
$ bash -c 'printf "Outside: $BASH_SUBSHELL , $SHLVL\nInside: $(echo $BASH_SUBSHELL , $SHLVL)\n"' 
Outside: 0 , 2 
Inside: 1 , 2 
$ bash -c '(printf "Outside: $BASH_SUBSHELL , $SHLVL\nInside: $(echo $BASH_SUBSHELL , $SHLVL)\n")' 
Outside: 1 , 2 
Inside: 2 , 2 

あなたの引用のソースは、(一般的に貧しい人々、そしてしばしばより良い回避、ABS)だけでも、別のインスタンス、少し(むしろ不明瞭な方法でこれを実証しますその「高度な」ガイド)での厳格さと品質の一般的な不足のため:

echo " \$BASH_SUBSHELL outside subshell  = $BASH_SUBSHELL"   # 0 
    (echo " \$BASH_SUBSHELL inside subshell  = $BASH_SUBSHELL")  # 1 
    ((echo " \$BASH_SUBSHELL inside nested subshell = $BASH_SUBSHELL")) # 2 
#^^       *** nested ***      ^^ 

echo 

echo " \$SHLVL outside subshell = $SHLVL"  # 3 
(echo " \$SHLVL inside subshell = $SHLVL") # 3 (No change!) 
+0

それは多くのことを助け、ありがとうございました。 –

5

$SHLVL:
シェルレベル、どの程度深くバッシュが入れ子になっていますか?コマンドラインで$ SHLVLが1の場合、スクリプトでは2に増加します。この変数はサブシェルの影響を受けません。

$BASH_SUBSHELL:
サブシェルレベルを示す変数。ここで

は、彼らが異なる値を持つことになります方法です。

# In the login bash shell 
echo $BASH_SUBSHELL:$SHLVL 
0:1 

# 1st nested child 
bash 
echo $BASH_SUBSHELL:$SHLVL 
0:2 

# 2nd nested child 
bash 
echo $BASH_SUBSHELL:$SHLVL 
0:3 

# back to 1st nested child 
exit 
echo $BASH_SUBSHELL:$SHLVL 
0:2 

# back to parent shell 
exit 
echo $BASH_SUBSHELL:$SHLVL 
0:1 

# first level sub-shell  
(echo $BASH_SUBSHELL:$SHLVL) 
1:1 

# 2nd level sub-shell 
((echo $BASH_SUBSHELL:$SHLVL)) 
2:1 

# 3rd level sub-shell 
(((echo $BASH_SUBSHELL:$SHLVL))) 
3:1