1

pkill发现和之间的有趣交互ssh。在这里记录它以供后代使用:

$ ssh user@remote 'false'; echo $?                                                              
1

$ ssh user@remote 'false || echo "failed"'; echo $?
failed
0

$ ssh user@remote 'pkill -f "fake_process"'; echo $?                                               
1

$ ssh user@remote 'pkill -f "fake_process" || echo "failed"'; echo $?
255

似乎示例#4应该与#2具有相同的输出;两者都用代码退出false并且没有输出。但是,#4 将始终以 code 退出,即使远程命令显式调用. 说明该代码的文档仅表示“发生错误”(超级有用)。pkill -f "fake_process"1255exit 0ssh255

用, ,等替换pkill命令都按预期工作。此外,在本地运行时(而不是通过),这些匹配符合预期。(exit 1)ls fake_filekill <non-existent PID>ssh

4

1 回答 1

0

问题似乎pkill是自杀。或者更确切地说,它正在杀死拥有它的外壳。

首先,它似乎ssh使用远程用户的 shell 来执行某些“复杂”的命令:

$ ssh user@remote 'ps -F --pid $$'
UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
user      9531  9526  0 11862  1616   6 14:36 ?        00:00:00 ps -F --pid 9531

$ ssh user@remote 'ps -F --pid $$ && echo hi'
UID        PID  PPID  C    SZ   RSS PSR STIME TTY          TIME CMD
user      9581  9577  0 28316  1588   5 14:36 ?        00:00:00 bash -c ps -F --pid $$ && echo hi
hi

其次,它似乎pkill -f通常知道不要杀死自己(否则所有pkill -f命令都会自杀)。但如果从子shell 运行,该逻辑将失败:

$ pkill -f fake_process; echo $?
1

$ sh -c 'pkill -f fake_process'; echo $?
[1]    14031 terminated  sh -c 'pkill -f fake_process'
143

就我而言,为了解决这个问题,我只是重新编写了ssh/周围的一些代码,pkill这样我就可以避免使用“复杂”的远程命令。理论上我认为你也可以做类似的事情pgrep -f <cmd> | grep -v $$ | xargs kill

于 2020-04-08T19:54:17.323 回答