我编写了一个 bash 脚本,它调用了几个其他程序并执行了一堆命令。我从终端运行这个脚本。现在我想终止该脚本。
有时按下Ctrl + C
不起作用,我想是因为有时脚本正在执行另一个程序,而由于某种原因,终止信号不起作用。
但是,如果我关闭终端窗口,它会终止脚本。
我可以做些什么(键盘组合),类似于关闭终端窗口,但实际上并不关闭终端窗口(我不想丢失命令历史记录、当前目录、输出历史记录等)?
答案1
您有几个选择。一个是停止脚本(CtrlZ),获取脚本的 PID 并发送SIGKILL
至进程组。
当在 shell 中执行命令时,它启动的进程及其所有子进程都是同一个进程组(在本例中为前台进程组)。要向该组中的所有进程发送信号,请将其发送给进程领导者。对于kill
命令,进程领导者表示如下:
kill -PID
PID
脚本的进程 ID 在哪里。
例子:
考虑一个启动一些进程的脚本test.sh
。假设你在 shell 中运行它:
$ ./test.sh
在另一个航站楼,
$ 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)
在这种情况下,要向创建的进程组发送信号test.sh
,你可以执行以下操作:
kill -INT -17802
-INT
用于发送SIGINT
,因此此命令相当于按下CtrlC终端上的 。要发送SIGKILL
:
kill -KILL -17802
如果您无法打开另一个终端,则只需停止脚本。如果可以,请使用pgrep
查找 PID。
脚本启动的命令之一可能是 trapping SIGINT
,这可能是CtrlC无效的原因。但是,SIGKILL
无法被捕获,通常是最后一招选项。你可能想在杀戮之前尝试SIGTERM
( )。两者都不能设置为-TERM
SIGKILL
SIGTERM
键盘快捷键方法SIGINT
是。
如果你的脚本不包含 shebang 行,那么这一切都毫无意义。从这个答案:
通常父 shell 会猜测该脚本是为同一个 shell 编写的(最小的 Bourne 类 shell 使用 /bin/sh 运行脚本,bash 将其作为 bash 子进程运行)...
因此,当执行脚本时,您将找不到以脚本命名的进程(或命令行中具有脚本名称的进程)并且pgrep
将会失败。
总是使用 shebang 行。
答案2
如果你知道与脚本关联的进程,你可以使用以下命令找到它们的 PID
ps -A
然后使用 PID 号来终止相应的进程
kill -9 PID_Number
答案3
正如哈里斯所说,您可以运行Kill -9 PID_Number
,但您也可以安装称为的软件包,以便htop
拥有一个交互式进程浏览器,使查找特定进程变得更加容易。htop 还支持终止进程。