Вы породили дочерний процесс, убили его и не wait(2)
для него. Теперь процесс превратился в зомби, околачивающегося вокруг своего родителя. Когда родительский процесс умирает, зомби становится сиротой, и init заботится о нем. Изman 2 wait
в Linux:
In the case of a terminated child, performing a wait allows the system to release the resources associated with the child; if a wait is not performed, then the terminated child remains in a "zombie" state (see NOTES below).
И из примечаний:
A child that terminates, but has not been waited for becomes a "zombie". The kernel maintains a minimal set of information about the zombie process (PID, termination status, resource usage information) in order to allow the parent to later perform a wait to obtain information about the child. As long as a zombie is not removed from the system via a wait, it will consume a slot in the kernel process table, and if this table fills, it will not be possible to create further processes. If a parent process terminates, then its "zombie" children (if any) are adopted by init(1), (or by the nearest "subreaper" process as defined through the use of the prctl(2) PR_SET_CHILD_SUBREAPER operation); init(1) automatically performs a wait to remove the zombies.
Итак, wait()
для дочернего процесса, иначе он будет зависать до тех пор, пока родительский процесс не умрет.
Вы не можете этого сделать.
Вы можете проверить его исходный код:
execve(actual_cmd, argv, envv);
err = errno;
// Something went wrong with execve, check for a ":", and run /bin/sh if encountered. This is a
// weird predecessor to the shebang that is still sometimes used since it is supported on
// Windows. OK to not use CLO_EXEC here because this is called after fork and the file is
// immediately closed.
Обратите внимание, что используется execve
(, а не execvp
или execlp
, которые имеют падение -обратно к /bin/sh path
в случае ENOEXEC
), и он запустит скрипт с /bin/sh
, только если он начинается с:
(сама по себе довольно сомнительная черта; тем более, что fish
также будет использовать его в случае ошибок, отличных от ENOEXEC
).
Но если вы можете отредактировать сценарий, чтобы добавить :
в начале, вы можете с тем же успехом отредактировать его, чтобы добавить правильную -чёлку.