我正在尝试编写一个 shell 脚本来杀死指定进程(如果它运行超过指定时间)并在杀死之前获取进程信息。
注意:脚本应将进程名称和时间作为输入。到目前为止我所尝试的如下:
#!/bin/sh
ps -eaf |
awk '{print $7, $8}' |
sort -n |
grep -v TIME |
grep -v 00:00:00 |
awk -F ":" '{if ( $2 >= 01 ) print}'
o/p 打印如下:
00:08:15 /usr/bin/dockerd
00:17:41 /usr/bin/kubelet
这就是我陷入困境的地方...我需要杀死超过 01 分钟的进程,因此需要使用脚本输入作为进程名称和时间来杀死上述进程。
答案1
恕我直言,您正处于死胡同中,无法以这种方式做您想做的事。
问题是您的TIME
信息已过时,因为该进程的属性可能TIME
在脚本运行时发生了更改。这对夫妇TIME
,CMD
无法识别过程。
你为什么这么做awk '{print $7, $8}'
?此时您不需要CMD
,只需要 来PID
识别进程,因此只需将其更改为awk '{print $7, $2}'
。
您可以按如下方式更改代码以打印PID
您正在搜索的进程的 s:
ps -eaf \
| awk '{print $7, $2}' \
| sort -n \
| grep -v TIME \
| grep -v 00:00:00 \
| awk -F ":" '{if ( $2 >= 01 ) print}' \
| awk '{print $2}'
此外,您的代码有一个微妙的错误:如果进程有04:00:23
as会发生什么TIME
?您的代码将跳过它,因为仅检查分钟场在TIME
.您可以这样修复它:
ps -eaf \
| awk '{print $7, $2}' \
| sort -n \
| grep -v TIME \
| grep -v 00:00:00 \
| awk -F ":" '{if (( $1 >= 01 ) || ( $2 >= 01 )) print}' \
| awk '{print $2}'
一些提高技能的建议:
- 您应该检查
-o
的选项ps
和-F
的选项,也许还有的列awk
的含义。TIME
ps
尝试理解下面这行代码是如何工作的:
ps -eo time,pid --no-headers | awk -F '[ :]*' '$1>0 || $2>0 {print $4}' | xargs kill
答案2
您可以使用以下命令获取以秒为单位的 CPU 时间以及 pid 和命令:
ps -Ao time= -o pid= -o comm= |
perl -lpe 's/^(\d+-)?(\d\d):(\d\d):(\d\d)/(($1*24+$2)*60+$3)*60+$4/e'
perl
您也可以使用以下命令进行杀戮:
ps -Ao time= -o pid= -o comm= |
perl -lne '
if (/^(\d+-)?(\d\d):(\d\d):(\d\d)\s+(\d+)\s+(.*)/) {
$cputime = (($1*24+$2)*60+$3)*60+$4;
$pid = $5;
$comm = $6;
if ($cputime > 60) {
print "$pid ($comm) has used $cputime seconds of CPU, killing it";
kill "TERM", $pid or warn "kill($pid): $!\n";
}
}'