bashのexecute_command_internal()の658行目あたりに子プロセスが実行する部分がある。
こんな感じ
pid_t paren_pid;
int s;
/*中略*/
paren_pid = make_child(/*sは使われない*/);
if (paren_pid == 0) {
s = (/*フラグとかを評価*/)
s += (/*フラグとかを評価*/)
last_command_exit_value =
execute_in_subshell(/*sは使われない*/)
/*ここで初めてsの値が使われる*/
if (s)
subshell_exit(last_command_exit_value);
else
sh_exit(last_command_exit_value);
}
/*これ以降sは使われない*/
コマンドがサブシェルで実行されるときは、このコードが実行されるっぽい。bashはmake_child()を呼び出して内部でfork()を呼び出す。そして、子プロセスはsにフラグの判定結果を代入して、その結果によってsubshell_exit()かsh_exit()を呼び出す
これら2つの関数は最終的にexit()を呼び出すだけで、メモリを開放する以外にあまり違いはないように見える。
ここまでの処理で疑問がある。
ローカル変数sは親プロセスでは使われておらず、サブシェル内で終了方法を判定する以外に使われていない。
プロセスはフォークするとそのプロセスのコピーがつくられつので、スタックやヒープの情報は保存されている。
なので、sを親プロセスで定義しているのはなんのためなのかがわからない。
つまり、上記のコードを以下のようにしたほうが良いのではないかと思った。
pid_t paren_pid;
/*中略*/
paren_pid = make_child(/*sは使われない*/);
if (paren_pid == 0) {
int s;
s = (/*フラグとかを評価*/)
s += (/*フラグとかを評価*/)
last_command_exit_value =
execute_in_subshell(/*sは使われない*/)
/*ここで初めてsの値が使われる*/
if (s)
subshell_exit(last_command_exit_value);
else
sh_exit(last_command_exit_value);
}
/*これ以降sは使われない*/
もしかしたら、完全に抜けている知識があるせいでこのような疑問を持ってしまうのかもしれないが、一応メモのために載せた。