“bash -c”コマンド実行で子プロセスが作られる時、作られない時
はじめに
KubernetesのマニフェストファイルやDockerのビルドファイル、Docker Composeの設定ファイルを閲覧、編集することが増えてきました。
それらのファイルの中で bash -c というコマンドが実行されていることがあります。bash の新しいプロセスを立ち上げ、 -c オプションで渡されたコマンドを実行する命令になります。
ps コマンドを使い、実行中の bash -c プロセスを見ていたところ、プロセスツリーの表示が時々で異なっていたため不思議に思い調べてみました。
検証環境
$ uname -moi
x86_64 x86_64 GNU/Linux
$ bash -version | head -n 1
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)改めて、 bash -c って何?
bash -c "echo hello" といったように、 -c コマンドに文字列を渡すことで、文字列をコマンドとして実行させることができます。
多くの言語系で実装されている eval 関数のようなものですね。
# 10秒待ってからhelloが表示される
$ bash -c "echo hogehoge"
hogehogeコマンドは ; で区切って複数実行させることもできます。
# 10秒待ってからhelloが表示される
$ bash -c "sleep 10; echo hello;"
hellobash -c "sleep 10; echo hello;" を実行したときのプロセスツリー
ここで、 bash -c "sleep 10; echo hello;" というコマンドを実行します。
$ bash -c "sleep 10; echo hello;"すかさず、別のターミナルで ps auf を実行します。 f オプションを付与すると子プロセスが親プロセスにぶら下がる形で表示されます。
$ ps auf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 19 0.0 0.0 11840 2952 pts/1 Ss 11:01 0:00 bash
root 44 0.0 0.0 51760 3360 pts/1 R+ 11:05 0:00 \_ ps auf
root 1 0.0 0.0 11840 2996 pts/0 Ss 11:01 0:00 /bin/bash
root 42 0.0 0.0 11700 2636 pts/0 S+ 11:05 0:00 bash -c sleep 10; echo hello;
root 43 0.0 0.0 4376 672 pts/0 S+ 11:05 0:00 \_ sleep 10プロセスがいくつも表示されていますが、 bash -c コマンドを実行した結果は一番下の2つのプロセスになります。
PID(プロセスID) = 42 のプロセスは bash -c "sleep 10; echo hello;" を実行しています。(ダブルクォーテーションはどこに行ってしまったんだろう? )
このプロセスがら派生した PID = 43 の子プロセスが sleep 10 を実行しています。
bash -c コマンドを実行した場合、 -c オプションに渡されたコマンドが子プロセスとして実行されるようです。
bash -c "sleep 10" を実行したときのプロセスツリー
今度は、 bash -c "sleep 10" という、単一のコマンドを実行するような文字列を指定してみます。
$ bash -c "sleep 10;"すかさず、別のターミナルで ps auf を実行します。
$ ps auf
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 19 0.0 0.0 11840 2952 pts/1 Ss 11:01 0:00 bash
root 46 0.0 0.0 51760 3524 pts/1 R+ 11:11 0:00 \_ ps auf
root 1 0.0 0.0 11840 2996 pts/0 Ss 11:01 0:00 /bin/bash
root 45 0.0 0.0 4376 628 pts/0 S+ 11:11 0:00 sleep 10先程とは異なり、 bash -c "sleep 10;" というプロセスがなく、 sleep 10 が親プロセスにぶら下がらずに実行されている ことがわかります。
bash -c がツリー状になったりならなかったり。ps aux | grep [b]ash といった形で実行中のプロセスを検索しているときに「あれ? bash 実行プロセスが見つからない。なぜだ?」となり、不思議に思っていました。
-c オプションで指定されたコマンドが単一の場合にはプロセスがツリーにならない
どうやら、Bashでは、 -c で渡されたコマンドが単一のコマンドだった場合には子プロセスを作らないようです。
( おそらく exec sleep 10 のようなことをしているのではないと思います。 )
ひとこと
bach -c で指定したジョブが正しく動作しているか確認したい場合など、 ps aux | grep [b]ash で検索して見つからない場合に参考になれば幸いです。
ディスカッション
コメント一覧
まだ、コメントがありません