サブシェルとは
サブシェルとは、以下のサンプルコードで言うと、4〜7行目にわたって「()」で括られたリストを指します。
「シェルスクリプトを実行する」とは、シェルが新たなシェルを子プロセスとしてメモリ上にロードし、その子プロセスが引数に指定されたスクリプトファイルを読み込み、ファイルに書かれた命令を順次実行する…ということですが、サブシェルは、その子プロセスから生成された孫プロセスで実行されます。
1 #!/bin/bash 2 3 func() 4 ( 5 ps -ef | grep `basename $0` | grep -v grep 6 exit 10 7 ) 8 9 echo PID=$$ 10 ps -ef | grep `basename $0` | grep -v grep 11 12 echo "########" 13 func 14 15 echo "########" 16 ps -ef | grep `basename $0` | grep -v grep 17 18 exit 0
実行結果
$ echo $$ 14367 $ bash ./hello.sh PID=14471 yz2cm 14471 14367 0 03:38 pts/1 00:00:00 bash ./hello.sh ######## yz2cm 14471 14367 0 03:38 pts/1 00:00:00 bash ./hello.sh yz2cm 14476 14471 0 03:38 pts/1 00:00:00 bash ./hello.sh ######## yz2cm 14471 14367 0 03:38 pts/1 00:00:00 bash ./hello.sh $
元のシェルはPID=14367ですが、hello.shを実行するシェルはPID=14471としてforkされています。さらに、hello.sh内のサブシェルはPID=14476で起動しています。つまり、サブシェルは元の「bash ./hello.sh」とは別のプロセスとして起動しているため、サブシェル内6行目でexitコマンドを呼び出していますが、その子プロセスが終了するだけで、hello.shの処理は終了しません。