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

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

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

$ 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는 bash라는 하위 프로세스를 시작합니다 pstree.

하지만 첫 번째 사람에게 무슨 일이 일어났는지 알고 싶습니다. 두 번째 프로세스가 bash사라지고 pstree원래 하위 프로세스가 되는 이유는 무엇입니까 bash? 이전 질문에 대한 답변이 두 번째 질문에 적용되지 않는 이유는 무엇입니까 bash -c ...?

답변1

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

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

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

zsh둘 다 ksh이 작업을 수행할 수 있는 것 같지만 다음과 같습니다 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)

관련 정보