~からこれリンク exec bash 組み込みコマンドに関する次の情報を取得します。
コマンドが提供されるとケースの交換新しいプロセスを作成する必要はありません。
シェルを正確にどのように置き換えますか(つまり、内部的にどのように機能しますか?)システムコールもexec*()
同じように機能しますか?
答え1
はい、組み込み関数は最終的にexec
システムコール系列の1つを使用します。exec*()
コマンドを正常に実行しても同様です。これを使用するときは、システムコールをexec
使用して最初に新しいプロセスを作成せず、その結果、新しいfork()
コマンドがシェルを置き換えます。
答え2
strace
実行中のインスタンスでbash
作成しました。その後、コマンドを呼び出しましたexec sleep 100
。今何が起こるのか見てください。
access("/bin/sleep", X_OK) = 0
...
execve("/bin/sleep", ["sleep", "100"], [/* 14 vars */]) = 0
...
nanosleep({100, 0},
...
exit_group(0) = ?
sleep
ご覧のとおり、通常の方法で呼び出すときに発生する状況とほぼ同じです。bash
システムコールが実行権限(X_OK
)を付与していることを確認してください。次に、ファイル名を指すプログラムを実行します。システムコール後にプロセスを制御できます。そのもの:。また、同じPIDを保持します。その後、プロセスは終了します。もう実行しないかどうか。/bin/sleep
access()
execve()
execve()
sleep
nanosleep()
sleep
sleep
bash
証拠:
別のウィンドウで私は全体のプロセスを見ましたps
。コマンドを実行する前の様子は次のとおりです。
$ ps -o stat,pid,cmd -p <pid>
Ss+ 10905 -bash
実行時:
$ ps -o stat,pid,cmd -p <pid>
Ss+ 10905 sleep 100
sleep
プロセスが終了すると消えます。
正常に実行するとどうなりますか?
access("/bin/sleep", X_OK) = 0
...
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f6c9fd089d0) = 19261
...
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WSTOPPED|WCONTINUED, NULL) = 19261
...
--- SIGCHLD (Child exited) @ 0 (0) ---
実行権限を確認してください。次にサブプロセスを作成しますclone()
。インスタンスbash
はバックグラウンドプロセスグループにあり、今ではsleep
フォアグラウンドプロセスグループにあります。最後に、子プロセスが完了するのを待つように呼び出されますwait4()
(100秒かかります)。