4

当我尝试结合另一个命令在远程主机上执行 pkill 时,它总是返回 255,即使这两个命令都成功了。

例子

  1. ssh <remoteHost> 'pkill -f xyz' # returns 0 (rightly so when xyz is a process)
    
  2. ssh <remoteHost> 'source /etc/profile' # returns 0 (rightly so)
    

但是当我运行组合命令时:

  1. ssh <remoteHost> 'source /etc/profile; pkill -f xyz' # returns 255 - why?
    

将“pkill”与另一个命令结合起来有些东西,因为即使它是一个组合,以下命令也会返回零:

  1. ssh <remoteHost> 'source /etc/profile; ls' # returns 0
    

假设xyz当我们试图杀死它时它一直在运行。

我不明白这种行为。为什么在案例 3 中返回 255?

4

1 回答 1

8

pkill -f选项的文档说:

-f
模式通常只与进程名匹配。设置 -f 时,将使用完整的命令行。

因此pkill -f xyz将在其命令行的任何位置使用“xyz”杀死任何进程。

当您运行ssh <remoteHost> 'source /etc/profile; pkill -f xyz'时,远程 ssh 服务器将代表您运行与此等效的操作:

$SHELL -c 'source /etc/profile; pkill -f xyz'

生成的 shell 实例是一个在其命令行中带有“xyz”的进程。我的猜测是它pkill正在杀死它,并且 ssh 将被杀死的会话报告为退出代码 255,如下所示:

$ ssh localhost 'kill $$'
$ echo $?
255

只是 run 时不会发生这种情况ssh <remoteHost> 'pkill -f xyz',因为像 bash 这样的一些 shell 会针对这种情况进行优化。shell 实例不会将 pkill 作为子进程运行,而是将其自身替换为 pkill 进程。因此,当 pkill 运行时,命令行上带有“xyz”的 shell 进程已经消失。

您可以通过像这样运行 pkill 来解决这个问题:

ssh <remoteHost> 'source /etc/profile; exec pkill -f xyz'

如果这不起作用,您可以指定 pkill 模式,使其与模式本身不匹配。例如:

ssh <remoteHost> 'source /etc/profile; exec pkill -f "[x]yz"'

该模式[x]yz匹配文本“xyz”,因此 pkill 将终止出现文本“xyz”的进程。但是模式本身并不匹配,所以 pkill 不会杀死模式出现的进程。

于 2016-11-07T21:45:01.437 回答