Как работает встроенная команда exec bash?

Как работает встроенная команда exec bash?

Отэтотссылка Я получаю следующее о встроенной команде exec bash:

Если команда предоставлена, оназаменяет оболочкубез создания нового процесса.

Как именно он заменяет оболочку (т.е. как он работает внутри)? Системный exec*()вызов работает так же?

решение1

Да, execвстроенная функция в конечном итоге использует один из 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предоставлено ли разрешение на выполнение ( ) для /bin/sleepсистемного access()вызова. Затем execve()выполняет программу, на которую указывает имя файла. После execve()системного вызова sleepимеет контроль над процессом. Делает свои вещи: nanosleep(). Он также сохраняет тот же pid. После 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 секунд).

Связанный контент