我编写了一个 bash 脚本,它调用其他几个程序并执行一堆命令。我从终端运行这个脚本。现在我想杀死脚本。
Ctrl + C有时按下并不会切断它,我认为是因为有时脚本正在执行另一个程序,并且出于某种原因终止信号不起作用。
但是,如果我关闭终端窗口,它会杀死脚本。
有什么我可以做的(键盘组合),类似于关闭终端窗口,而不实际关闭终端窗口(我不想丢失命令历史记录、当前目录、输出历史记录等)?
mur*_*uru 43
你有几个选择。一种是停止脚本(CtrlZ),获取脚本的PID并发SIGKILL送给进程组。
在 shell 中执行命令时,它启动的进程及其所有子进程都属于同一个进程组(在本例中为前台进程组)。要向该组中的所有进程发送信号,请将其发送给进程领导者。对于kill命令,进程领导者表示为:
kill -PID
Run Code Online (Sandbox Code Playgroud)
PID脚本的进程ID在哪里。
例子:
考虑一个test.sh启动一些进程的脚本。假设您在 shell 中运行它:
$ ./test.sh
Run Code Online (Sandbox Code Playgroud)
在另一个终端,
$ pgrep test.sh
17802
$ pstree -ps `!!`
pstree -ps `pgrep test.sh`
init(1)???sshd(1211)???sshd(17312)???sshd(17372)???zsh(17788)???test.sh(17802)???dd(17804)
??sleep(17805)
??yes(17803)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,要向由 创建的进程组发送信号test.sh,您可以执行以下操作:
kill -INT -17802
Run Code Online (Sandbox Code Playgroud)
-INT用于发送SIGINT,所以这个命令相当于CtrlC在终端上按下。发送SIGKILL:
kill -KILL -17802
Run Code Online (Sandbox Code Playgroud)
如果您无法打开另一个终端,您只需要停止脚本。如果可以,请使用pgrep查找PID。
脚本启动的命令之一可能是 trapping SIGINT,这可能CtrlC是无效的原因。但是,SIGKILL不能被困,通常是不得已的选择。您可能想尝试SIGTERM( -TERM) 后再进行杀戮。无论是SIGKILL或SIGTERM可以被设置为快捷键的方式SIGINT是。
如果您的脚本不包含 shebang 行,则所有这些都没有实际意义。从这个 SO 答案:
通常父 shell 猜测脚本是为同一个 shell 编写的(最小的类似 Bourne 的 shell 使用 /bin/sh 运行脚本,bash 将它作为 bash 子进程运行)......
因此,在执行脚本时,您将找不到以脚本命名的进程(或命令行中具有脚本名称的进程)并且pgrep会失败。
始终使用shebang线。
如果您知道与脚本关联的进程,您可以使用以下命令找到它们的 PID
ps -A
Run Code Online (Sandbox Code Playgroud)
然后使用PID号杀死相应的进程使用
kill -9 PID_Number
Run Code Online (Sandbox Code Playgroud)