この質問は、 以前に投稿した「シェルで単純なコマンドを入力するとどうなりますか?」 の質問に関連しています。 (個別に投稿した方がいいと思いましたが、そうでない場合はお知らせください。)
前の質問 から、シェル組み込みコマンドは特別に扱われ、通常の外部コマンドは子プロセスで実行されることがわかりました。
今回は、fork、clone、execveなどのシステムコールをトレースして、コマンドの入力後に実際に何が起こったかを監視します。ただし、このようにstrace
を実行すると、execve呼び出しexecve("bin/ls",,,) = 0
のみをトレースできます。
strace -etrace=execve,clone ls
つまり、私が推測しているように、子プロセスが作成された後に呼び出されるシステムコールしか監視できません。
新しいプロセスの作成に関連するすべてのシステムコールを監視するには、何をする必要がありますか?この場合、bash -c
のようにstrace -etrace=execve,clone bash -c '{ ls; }'
を使用してコマンドを呼び出すと役に立ちますか?
前の質問の answers の1つで述べたように、exec
ファミリーの呼び出しは子プロセスが作成された後に発生するため、strace
出力に表示したい場合は、それも従う必要がありますトレースしているシェルプロセスの子。
これを行うには、-f
または-ff
オプションを追加します。関連するmanページのスニペットを次に示します。
-f Trace child processes as they are created by currently traced processes as a
result of the fork(2) system call.
-ff If the -o filename option is in effect, each processes trace is written to
filename.pid where pid is the numeric process id of each process. This is
incompatible with -c, since no per-process counts are kept.
bash
でコマンドを実行することに関連する呼び出しを追跡するには、次のようにします。
strace -f -e trace=process bash -c 'ls; :'
-e trace=process
は、特にプロセス管理に関連するすべての呼び出しをトレースします。また、2つ目のno-opコマンド(:
)も必要です。これは、単一のコマンドのみでbashを実行する場合と同じです。execve
をフォークせずに実行するだけで十分です。