exec コマンド
今回はシェルのプロセスを
置き換える方法を学ぼう!
え?
意味がよくわからないんですけど?!
プロセスを置き換える
理由を理解するために
まずはプロセスの
親子関係の話から入ろう
プロセスには
親子関係があって
親プロセスから
子プロセスが
作られるんだよね?
そうそう
その話だよ!
今動いているシェルを
pstree の表示のように
表現してみよう
bash
このシェル
bash が私のコマンド入力を処理してくているんだよね!そういうことになるねこのシェルからシェルスクリプトを実行したとしようそのときの親子関係はこのようになるんだ
bash ─── bash
うんこれは理解できるよ!親の
bash が私の入力を受け付けるシェルで子の bash がシェルスクリプトを解釈するシェルというわけだね!そのとおり!
ここで実行しているシェルスクリプトが以下のようなものだったとしよう
#!/bin/bash
ls -l "$@"
ls に -l オプションを付けてくれるスクリプトだね!このシェルスクリプトで
ls が実行されるとこのようになるのはわかるかなbash ─── bash ─── ls
そうなるよね
でもこうやって見てみるとシェルスクリプトのシェル2番目の
bash が余計に感じるなぁだって ls を呼び出しているだけでしょ?このように一つのコマンドを便利にしたりするスクリプトを「ラッパースクリプト(wrapper script)」 と呼ぶよ
メインとなるコマンドを「つつんで(wrap)」 便利にしてあげているんだね
このようなラッパースクリプトで使われるのが
exec なんだexec [オプション]... [コマンド]
これは
exec を動かしたシェルのプロセスをコマンド のプロセスに置き換えてくれるよさっきのスクリプトの例だとこんな感じになるよ
#!/bin/bash
exec ls -l "$@"
じゃあこのスクリプトを実行すると親子関係はこうなっちゃうんだ?!
bash ─── ls
そのとおり!シェルスクリプトを動かしていた
bash のプロセスがls のプロセスに置き換わるんだbash プロセスがls に置き換わっちゃうんでしょ?exec より後に記述があったらどうなっちゃうのかな?ls のプロセスが処理を終えた時点で終了になるよシェルスクリプトを解釈していた bash は置き換えられて動いていないからねだから exec 以降に記述があったとしてもそれらの記述は実行されないことになるんだつまり
exec はラッパースクリプトの最後で使うんだね!今回はシェルのプロセスを置き換える
exec を学んだよ!ラッパースクリプトで使われるよ!exec はリダイレクトを組み合わせ3番以降のファイルディスクリプタを使う目的でも利用されるんだこれは高度な使い方なのでここでは説明はしないけど興味があれば