如何从从脚本中杀死主脚本?(在bash中)

如何从从脚本中杀死主脚本?(在bash中)

我正在尝试制作一个“工具包”,我想要的是它具有“退出”功能。这意味着每当我调用“退出”时,我开始的任何事情都应该停止。但是,不仅仅是工具包脚本,还有主脚本。含义如下:

让 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

您可以添加一个trapinA.sh来让A干净地退出,而不是通过 SIGTERM 来触发Terminated来自调用 shell 的消息。

更好的解决方案可能是其中的任何命令退出非零时set -eA.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

相关内容