저는 bash 프로세스에 대해 잘 알지 못하는데 파이프와 tee
.
아래에서는 스크립트 경로가 로 대체됩니다 $FOLDER
.
$FOLDER/DBB/myparent.ksh
:echo "BEGIN $$ this is the parent process" $FOLDER/DBB/myChild.ksh echo "END $$ this is the parent process"
$FOLDER/DBB/mychild.ksh
:function toto { echo " this is $$ child process " sleep 10 } { echo " $$ go1 " toto ptree $$ echo " $$ go2 " } | tee myLog$$.log
을(를 ) 시작하면
myParent.ksh
다음과 같은 프로세스 트리가 표시됩니다.28417 /usr/lib/ssh/sshd -R 28531 -ksh 41387 /bin/bash myParent.ksh 41390 /bin/bash $FOLDER/DBB/myChild.ksh 41391 /bin/bash $FOLDER/DBB/myChild.ksh 41393 sleep 10 41392 tee myLog41390.log
콘솔 출력:
BEGIN 52665 this is the parent process in myChild.ksh 52680 go1 this is 52680 child process 20192 zsched 21104 /usr/lib/ssh/sshd 27882 /usr/lib/ssh/sshd -R 28417 /usr/lib/ssh/sshd -R 28531 -ksh 52665 /bin/bash myParent.ksh 52680 /bin/bash $FOLDER/DBB/myChild.ksh 52688 /bin/bash $FOLDER/DBB/myChild.ksh 61896 ptree 52680 52692 tee myLog52680.log 52680 go2 END 52665 this is the parent process
왜 2개인가요 $FOLDER/DBB/myChild.ksh
?
답변1
셸 스크립트에는 접미사가 붙지 .ksh
만 프로세스 트리에서는 해당 스크립트가 실제로 bash
셸에 의해 실행됨을 나타냅니다.
내 Debian 11 man ksh
(실제로는 mksh
MirBSD Korn 쉘)에서는 다음과 같이 말합니다:
파이프의 모든 명령은 별도의 하위 쉘에서 실행됩니다. 이는 POSIX에서 허용되지만 마지막 명령을 제외한 모든 명령이 하위 쉘에서 실행되는 AT&T UNIX ksh의 두 가지 변형과 다릅니다. 의미와 해결 방법을 위한 기능입니다.
그리고 man bash
말했다:
파이프라인의 각 명령은 별도의 프로세스(즉, 하위 셸에서)로 실행됩니다. [...]
lastpipe
내장 기능을 사용하여 이 옵션을 활성화 하면shopt
(아래 설명 참조shopt
) 파이프의 마지막 요소가 쉘 프로세스에 의해 실행될 수 있습니다.
따라서 초기에 프로세스 #41390이 실행을 시작하는 프로세스입니다 myChild.ksh
. 파이프가 보일 때:
{
echo " $$ go1 "
toto
ptree $$
echo " $$ go2 "
} | tee myLog$$.log
$$
파이프를 확장한 다음 {
#41391의 복합 명령에 대한 하위 쉘 프로세스를 포크합니다 }
.
프로세스 #41392는 내부가 아닌 명령을 실행하고 이를 최적화로 처리해야 하는 하위 쉘일 수도 있고 exec()
상위 프로세스 #41390에 의해 tee
직접 fork()
명령 + 'd 될 수도 있습니다. exec()
두 경우 모두 동일한 결과를 낳습니다. #41392는 보이는 명령줄을 변경하는 exec()
작업을 수행하게 됩니다.exec()
ptree
반면, 서브셸 #41391에는 실행할 명령이 여러 개 있으므로 프로세스 #41391은 서브셸로서의 정체성을 유지합니다. 실행해야 하는 마지막 명령은 echo
셸 내부 명령이므로 하위 셸 프로세스로서의 수명이 종료됩니다. 그리고 파이프라인 실행을 준비할 때 상위 #41390이 $$
이미 s를 확장했으므로 하위 셸 #41391의 PID는 출력에 표시되지 않습니다.