sudo가 항상 쉘 하위 프로세스를 생성하지 않는 이유는 무엇입니까?

sudo가 항상 쉘 하위 프로세스를 생성하지 않는 이유는 무엇입니까?

호출할 때 특정 쉘이 특별 대우를 받는 것처럼 보이는 이유를 이해하려고 노력 중입니다.스도. 예를 들어, 두 가지 가능한 동작이 있는 것 같습니다.

"암시적" 그룹(나무응 직계존속스도, 중간에 쉘 없음):

$ sudo pstree -s $$
systemd───login───bash───sudo───pstree
$ sudo bash -c 'pstree -s $$'
systemd───login───bash───sudo───pstree
$ sudo zsh -c 'pstree -s $$'
systemd───login───bash───sudo───pstree
$ sudo dash -c 'pstree -s $$'
systemd───login───bash───sudo───pstree

"명시적" 그룹(쉘은스도):

$ sudo ksh -c 'pstree -s $$'
systemd───login───bash───sudo───ksh───pstree
$ sudo tcsh -c 'pstree -s $$'
systemd───login───bash───sudo───tcsh───pstree
$ sudo fish -c 'pstree -s $fish_pid'
systemd───login───bash───sudo───fish───pstree

분명히 둘 사이에 일종의 통합이 이루어진 것 같습니다 .스도및 일부 쉘이 있지만 관련 문서를 찾을 수 없습니다. 나는 또한 두 가지의 소스 코드를 grep합니다.스도그리고세게 때리다하지만 아무런 단서도 찾을 수 없었습니다.

이 다른 질문은 관련이 있는 것 같습니다.백그라운드에서 실행될 때 왜 (...) 새 하위 프로세스를 생성하지 않습니까?

내 버전스도그리고세게 때리다예:

$ sudo --version
Sudo version 1.8.29
...
$ bash --version
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
...

답변1

아니요, 이것은 쉘과 sudo 사이의 상호 작용이 아닙니다. 이는 사용자가 실행하는 명령으로 대체되는 작업 수행을 담당하는 쉘입니다!

전체에서 sudo를 제거하면 동일한 결과를 얻을 수 있습니다. 예를 들어 alacritty 터미널에서 zsh를 실행합니다.

$> bash -c 'pstree -s $$'
systemd───alacritty───zsh───pstree

여기에는 배쉬가 없습니다!

다음을 실행하여 무슨 일이 일어나는지 확인할 수 있습니다.

$> strace -o /tmp/bash-pstree.strace bash -c 'pstree -s $$'
systemd───alacritty───zsh───pstree
$> bat /tmp/bash-pstree.strace # or just less /tmp/.... ; bat is just a nice code highlighter

우리가 보는 곳

$> grep execve /tmp/bash-pstree.strace
execve("/usr/bin/bash", ["bash", "-c", "pstree -s $$"], 0x7ffc02c52d30 /* 102 vars */) = 0
execve("/usr/bin/pstree", ["pstree", "-s", "35735"], 0x55b90ec78d00 /* 102 vars */) = 

따라서 첫 번째 execve는 bash가 호출되고 두 번째 execve는 bash가 pstree로 대체되는 것입니다. 그러면 더 이상 실제로 bash가 없습니다! 그 사이에는 분기/복제가 발생하지 않습니다.

물론 이는 다음에만 적용됩니다.마지막명령 체계의 명령입니다. 이전에 실행한 명령으로 교체하면 이후에는 아무 것도 할 수 없습니다. 실제로 이를 매우 쉽게 확인할 수 있습니다.

$> bash -c 'pstree -p -s $$; pstree -p -s $$'                                                                                                                                                                                                        
systemd(1)───alacritty(34604)───zsh(34609)───bash(39257)───pstree(39258)
systemd(1)───alacritty(34604)───zsh(34609)───pstree(39257)

여기에서 첫 번째 pstree는 실제로 bash가 생성한 프로세스에서 실행되고 있고 두 번째 pstree는 bash를 대체하는 동일한 프로세스에 의해 실행됩니다.

셸을 실행되는 프로그램으로 바꾸는 것은 리소스 관점에서 볼 때 물론 좋은 일입니다. 모든 파일 핸들, 메모리, 잠금 등을 가능한 한 빨리 생성합니다.

왜 일부 쉘에서는 이 작업을 수행하고 다른 쉘에서는 수행하지 않는지 모르겠습니다( 지정된 명령을 실행하기 전에 자체 프로세스를 사용 fork하거나 복제할 수 있음). 아마도 이것은 개발자가 결코 생각하지 못한 최적화일 것입니다( 예: 쉘이 시작된 프로세스에 대해 일부 제어를 유지하므로 릴리스는 10년 전이었습니다!).cloneexecvefishksh

관련 정보