pkill通过远程ssh返回255和另一个命令的组合

Moh*_*han 3 linux ssh pkill

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

例子

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

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

  1. ssh <remoteHost> 'source /etc/profile; pkill -f xyz' # returns 255 - why?
    
    Run Code Online (Sandbox Code Playgroud)

关于“ pkill”与另一条命令的结合是有一些问题的,因为即使结合使用,以下内容也会返回零:

  1. ssh <remoteHost> 'source /etc/profile; ls' # returns 0
    
    Run Code Online (Sandbox Code Playgroud)

假设xyz当我们试图杀死它时,它始终在运行。

我不了解这种行为。为什么在情况3中返回255?

Ken*_*ter 5

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'
Run Code Online (Sandbox Code Playgroud)

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

$ ssh localhost 'kill $$'
$ echo $?
255
Run Code Online (Sandbox Code Playgroud)

仅在运行时不会发生这种情况ssh <remoteHost> 'pkill -f xyz',因为某些外壳(如bash)会针对这种情况进行优化。Shell实例不是将pkill作为子进程运行,而是将其自身替换为pkill进程。因此,在运行pkill时,其命令行上带有“ xyz”的shell进程已消失。

您可以通过运行pkill来解决此问题:

ssh <remoteHost> 'source /etc/profile; exec pkill -f xyz'
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,则可以以与模式本身不匹配的方式指定pkill模式。例如:

ssh <remoteHost> 'source /etc/profile; exec pkill -f "[x]yz"'
Run Code Online (Sandbox Code Playgroud)

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