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