我需要创建一个while
循环,如果dmesg
返回一些/任何值,那么它应该杀死一个确定的进程。
这是我所拥有的。
#!/bin/bash
while [ 1 ];
do
BUG=$(dmesg | grep "BUG: workqueue lockup" &> /dev/null)
if [ ! -z "$BUG" ]; then
killall someprocessname
else
break
fi
done
我不知道我是否! -z
应该这样做[ test -n "$BUG" ]
我认为 -n 表示期待二进制文件。
我不知道该脚本是否会起作用,因为 BUG 锁定会停止每个进程,但在计算机完全崩溃之前仍然还有几行dmesg
- 也许我可以赶上并终止该进程。
答案1
一些问题:
- 您正在一个繁忙的循环中运行它,这将消耗尽可能多的资源。这是
sleep
可以想象 ing 是合理的一个例子。 然而,最新版本
dmesg
有一个标志来跟随输出,所以你可以将整个事情重写为(未经测试)while true do dmesg --follow | tail --follow --lines=0 | grep --quiet 'BUG: workqueue lockup' killall someprocessname done
- 代码应该缩进以便可读。
- 这确实很奇怪,但与- see
[
相同。test
help [
答案2
@l0b0 的答案的一个变体:
dmesg --follow | awk '
/BUG: workqueue lockup/ { system ("killall someprocessname") ; rem="done at each occurrence. You could add further things, like print to a logfile, etc.,"
}'
这让 awk 进行循环,它有一些优点:
- 它会一直工作,直到该进程终止。
killall
每次出现搜索字符串“BUG:工作队列锁定”时,它也不会调用超过 1 次,这改进了其他答案。
测试:您可以将其放入名为thescript
、 和 do 的脚本中nohup thescript &
,这样thescript
即使在退出会话后该脚本也会继续运行。
一旦您对它的工作感到满意,就杀死它,然后您可以(而不是每次在 shell 中使用 运行它nohup
)将其转换为daemon script
您可以在当前运行级别启动的 。
即:使用另一个脚本作为模型(您至少需要有开始、停止和状态部分),您可以进行thescript
适当修改,然后将其放置在 中,并在适当的下/etc/rc.d/init.d
命名一个符号链接,作为正常运行级别的编号(请参阅 的顶行以了解当前的运行级别)。并且在每个(或几乎每个)运行级别中也有适当的符号链接,以便在切换运行级别时适当地终止脚本。Sxxthescript
/etc/rc.d/rcN
N
who -a
Kxxthescript
或者做“适当的事情”以通过 systemd 或您的发行版使用的任何等效系统运行/停止它。