我有一个简单的 Docker 命令来终止数据库进程:
docker exec app-pgsql bash -c 'ps axuf |grep ils |cut -d" " -f3 |xargs kill -9 || :'
正如您所看到的,我正在寻找第 3 列以ps
获取进程 ID,但有时此列不同,一次是第 3 列,第二次是第 4 列,下一次还是第 3 列,等等。
有没有更好的解决方案来解决这个问题,不管第 3 列是什么?
答案1
首先:正如@HBruijn 在评论中所说,使用 pkill,因为在您的问题中使用该方法至少是脆弱的。
如果您仍想继续ps | filter_it | kill_it
,我会尝试找出您尝试运行的命令中的一些错误。这可能无法回答您的问题,但将其作为注释包含会有点太长,所以我们就在这里。
首先,我不明白进程 ID 怎么会出现在不同的列中,对我来说,当我使用 时ps axuf
,PID 位于第二列。也许你正在使用的另一个版本具有不同的默认值。你可以使用开关ps
控制 的输出,因此如果你使用类似ps
-o
ps -ho pid,command
那么 PID 将始终位于第一列。
其次,如果您使用 grep,您可能还想使用第二个grep -v
。在管道命令时,shell 将保持所有进程处于活动状态。由于grep ils
它本身包含ils
,因此它很可能出现在您的最终列表中。因此,如果您使用grep
过滤,请务必排除grep
它本身,如下所示:
ps -ho pid,command | grep ils | grep -v grep
第三,使用cut
不是处理列文本的好方法,因为如果有两个分隔符,cut
会将输入视为具有额外的空列,从而使输出变得模糊(有点)。请使用其他方法,例如awk
。
所以你的最终命令应该是这样的:
ps -ho pid,command | grep ils | grep -v grep | awk '{print $1}' | xargs kill -9
在这种情况下,awk
您可以使用cut
(或实际上任何内容,例如sed
)而不是使用,因为 PID 保证是第一列,所以cut
这样做。我很少使用它cut
并尽量避免使用它,因此,awk
。:)
最后注意:使用kill -9
通常被视为“最后的手段”。您应该尝试以正常方式结束该过程,因为kill -9
无论如何都会结束该过程,这可能会导致各种有趣的效果,尤其是对于数据库而言。