나는 "툴킷"을 만들려고 노력하고 있는데 내가 원하는 것은 "종료" 기능을 갖는 것입니다. 이는 내가 "exit"을 부를 때마다 내가 시작한 모든 것이 중지되어야 함을 의미합니다. 그러나 이는 툴킷 스크립트일 뿐만 아니라 기본 스크립트이기도 합니다. 의미는 다음과 같습니다.
A.sh를 메인 스크립트로 둡니다. 어떤 시점에서 A.sh는 B.sh를 실행하여 사용자에게 옵션을 제공합니다. B.sh에 항상 "종료" 옵션이 있었으면 좋겠습니다. 선택하고 나면 B.sh를 종료해야 하며(쉬우면 "exit"를 실행하면 됩니다) A.sh도 종료됩니다.
물론 나는 이것을 할 수 있다
if [[ $(B.sh) == "exit" ]]; then exit; fi
그러나 이것은 기껏해야 지루한 작업이며 일반적으로 "툴킷"이 수행해야 하는 작업이 아닙니다.
어떻게 할 수 있는지 아이디어가 있습니까? 건배.
답변1
적어도 Linux에서는 하위 스크립트가 상위 프로세스 그룹을 종료하도록 할 수 있습니다. 이렇게 하면 상위 프로세스 자체와 해당 프로세스가 시작한 모든 하위 프로세스가 종료됩니다. 에서 man kill
:
ARGUMENTS
The list of processes to be signaled can be a mixture of names and
PIDs.
[. . .]
-n
where n is larger than 1. All processes in process group n are
signaled. When an argument of the form '-n' is given, and it
is meant to denote a process group, either a signal must be
specified first, or the argument must be preceded by a '--'
option, otherwise it will be taken as the signal to send.
따라서 귀하의 기능은 다음과 같을 수 있습니다.
killGroup(){
pgid=$(ps -p "$$" -o pgid=)
kill -- -"$pgid"
}
그러면 프로세스 그룹 ID를 가져오고 이를 실행하여 kill
해당 그룹 ID 아래의 모든 프로세스를 종료합니다.
답변2
분명히 해킹적이지만 질문에 대답하려면 를 통해 상위 bash 스크립트에 액세스할 수 있습니다 $PPID
.
$ cat > A.sh
#!/bin/bash
/bin/bash B.sh
echo "A continues"
exit 0
$ cat > B.sh
#!/bin/bash
echo "B entered"
kill $PPID
sleep 3
echo "B finishes"
exit 0
$ bash A.sh
B entered
Terminated
$ B finishes
호출 셸에서 SIGTERM 메시지를 트리거하는 대신 trap
in을 추가하여 깔끔하게 종료 A.sh
할 수 있습니다.A
Terminated
더 나은 해결책은 명령이 0이 아닌 값으로 종료되면 명령이 종료 set -e
되는 것입니다 .A.sh
A.sh
$ cat >A.sh
#!/bin/bash
set -e
bash B.sh
echo "A continues"
exit 0
$ cat > B.sh
#!/bin/bash
echo "B finishes with exit code 1"
exit 1
$ bash A.sh
B finishes with exit code 1
$ echo $?
1