我正在尝试制作一个“工具包”,我想要的是它具有“退出”功能。这意味着每当我调用“退出”时,我开始的任何事情都应该停止。但是,不仅仅是工具包脚本,还有主脚本。含义如下:
让 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
显然是 hackish,但要回答这个问题:您可以通过 访问父 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
您可以添加一个trap
inA.sh
来让A
干净地退出,而不是通过 SIGTERM 来触发Terminated
来自调用 shell 的消息。
更好的解决方案可能是其中的任何命令退出非零时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