make
当我从 shell运行命令(在大型项目上)时,我可以键入命令CtrlZ来停止进程并返回到 shell。随后,我可以运行fg
以继续该过程。
我正在尝试编写一个 shell 脚本来自动执行此操作(具体来说,每隔几秒检查一次 CPU 温度,如果温度太高,则停止该进程,因为我的计算机很容易过热)。我的第一次尝试是这样的(简化的):
make &
subpid="$!"
sleep 2
# If the CPU temperature is too high...
kill -STOP "$subpid"
sleep 2
# If the CPU temperature has dropped to safe levels...
kill -CONT "$subpid"
wait "$subpid"
不幸的是,这并没有奏效;发送SIGSTOP
到进程并没有暂停它(从它继续将输出发送到终端可以看出)。我make &
在命令行中运行,发送SIGSTOP
,并使用 ; 检查进程状态ps
。它被列为已停止(并在我发送时再次启动SIGCONT
),但它仍在喷出输出并提高了我的核心温度!停止它从来CtrlZ没有遇到过这个问题,但我不知道如何在脚本中做到这一点。
与有何CtrlZ不同kill -STOP
,如何在 shell 脚本中获得前者的行为?
答案1
Ctrl-Z 与 有何不同
kill -STOP
,如何在 shell 脚本中获得前者的行为?
CTRL-Z
通常会发送 SIGTSTP(可以被阻止),并且除了其他事情之外,shell 经常在这些情况下将 tty 重置为之前保存的状态。然而更重要的是,控制终端进程组被设置为 shell 的 PID(然后再次设置为使用 恢复的作业的 PID fg
)。
回到原来的问题:使用依赖于温度的频率缩放,例如CPU频率实际上可能是一把更好的钉子锤子。
答案2
如果指定负 PID 值 - 会话领导者的 PGID,则可以向进程组中的所有进程发送信号。
kill -STOP -"$subpid"
注意:要在新会话中运行程序,请使用setsid make
.但就你的情况我认为没有必要。但是,如果 make 递归运行,则每个 make 实例都可以是它自己的领导者(我对此不确定)。
另一种选择可能是使用killall
:
killall -STOP make
Ctrl+Z 和kill -STOP 的区别:
- Ctrl-Z 实际上发送 TSTP,可以阻止。
- STOP 无法被阻止。
答案3
你不想停止这个make
过程;你想停止这个make
过程和它的所有子进程。我敢打赌 make 正在递归运行。
您可以尝试set -m
,然后使用%1
代替"$subpid"
。
启用“作业控制”,该功能set -m
在脚本内默认处于关闭状态。我认为它应该适合你的用例,尽管人们似乎普遍认为这是一个坏主意。
答案4
Ctrl+C用于通过信号杀死进程SIGINT
,换句话说,这是一种礼貌杀。
Ctrl+Z 用于通过向进程发送信号来暂停进程信号传输协议,这就像一个睡眠信号,可以撤消并且可以再次恢复进程。
然而,当一个进程被挂起时,我们可以通过以下方式再次恢复它:fg
(在前台恢复)和bg
(在后台继续),但我无法恢复已终止的进程,这是使用Ctrl+ C& Ctrl+之间的区别Z。
如何看法暂停进程?
当您有多个挂起的命令时,要列出它们,您可以使用该jobs
命令,输出将为:
[1]- Stopped cat
[2]+ Stopped vi
如何杀后台挂起的进程?
通过使用kill
命令:
kill %n
在哪里n是作业编号(作业输出中方括号中的编号),所以我想杀死 cat : kill %1
。