`bash -c somecommand`가 때때로 bash 프로세스를 종료하지 않는 이유는 무엇입니까?

`bash -c somecommand`가 때때로 bash 프로세스를 종료하지 않는 이유는 무엇입니까?

GNU bash 버전 4.2.25(1)-릴리스(x86_64-pc-linux-gnu)를 사용하는 Ubuntu 12.04에서 다음 명령을 시도했습니다.

$ bash -c 'pstree -s $$'
init───sshd───sshd───sshd───bash───pstree
$ bash -c 'pstree -s $$;echo'
init───sshd───sshd───sshd───bash───bash───pstree

두 번째는 내 예상대로라고 생각합니다. 첫 번째 bash는 제가 이 명령을 실행한 곳입니다. 두 번째 bash는 내가 시작한 것입니다 bash -c .... 그런 다음 두 번째 bash는 이라는 하위 프로세스를 시작합니다 pstree.

그런데 첫 번째 사건은 어떻게 되었는지 궁금합니다. 두 번째가 bash사라지고 pstree원본의 하위 프로세스가 된 이유는 무엇입니까 bash? 그리고 이전 질문에 대한 답변이 두 번째 질문에는 왜 적용되지 않습니까 bash -c ...?

답변1

나는 그것이 단순히라고 말했을 것이다.꼬리 부르다 최적화, 그러나 실제로는 (마지막 링크에서 알 수 있듯이) bash테일 호출을 최적화하지 않습니다. 리디렉션이 있는 경우는 아니지만 실행할 명령이 간단한 명령(즉, 복합 명령이 아닌)인 경우에만 최적화된 것으로 보입니다. 또한 명령이 and-or 목록에서 마지막인 경우( true && true && cmdor 에서처럼 false && true || cmd) 최적화하는 것처럼 보이지만 s가 제자리에 있을 때는 trap( 에서처럼 trap uname EXIT && cmd) 그렇게 하는 것이 올바르지 않기 때문에 최적화되지 않는 것 같습니다.

두 번째 명령은 명령줄의 마지막 명령이 아니기 pstree때문에 의 마무리 호출이 아닙니다. pstree( 의 테일 콜이지만 echo일반적 echo으로 내장되어 있으므로 이에 관계없이 하위 프로세스가 생성되지 않습니다.)

모든 링크를 읽는 시간을 절약하기 위해(재미있기를 바라지만) 함수/프로그램/무엇이든 다른 함수/프로그램/무엇이든 호출한 후 즉시 반환되고 반환된 값은 호출된 함수/프로그램/무엇이든 반환된 값이 있으면 새 스택 프레임을 푸시(새 프로세스 생성)하는 대신 현재 스택 프레임(또는 쉘 스크립트의 경우 프로세스)을 재사용하여 함수(스크립트 실행)를 실행한 다음 반환합니다. 쉘 스크립트에서는 마지막 명령을 사용하여 수동으로 수행할 수 있지만 exec쉘이 자동으로 수행하는 것도 가능합니다.

zshksh다 그렇게 할 수 있는 것 같지만 그렇지 않습니다 bash.

$ zsh -c 'if [[ -n foo ]]; then pstree -s $$; else echo hello; fi'
init───lightdm───lightdm───init───konsole───bash───pstree
$ ksh -c 'if [[ -n foo ]]; then pstree -s $$; else echo hello; fi'
init───lightdm───lightdm───init───konsole───bash───pstree
$ bash -c 'if [[ -n foo ]]; then pstree -s $$; else echo hello; fi'
init───lightdm───lightdm───init───konsole───bash───bash───pstree

그러나 그 관찰은 내가 우연히 설치한 쉘 버전을 기반으로 한 관찰일 뿐이므로 YMMV는 다음과 같습니다.

$ zsh --version
zsh 5.0.2 (x86_64-pc-linux-gnu)
$ ksh --version
  version         sh (AT&T Research) 93u+ 2012-08-01
$ bash --version
GNU bash, version 4.2.45(1)-release (x86_64-pc-linux-gnu)

관련 정보