发现了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
和pkill -f "fake_process"
都以代码1
退出并且没有输出。 但是,#4 将始终以代码255
退出,即使远程命令显式调用exit 0
也是如此。ssh
的文档指出,代码255
只是意味着"发生了错误"(超级有用)。
将pkill
命令替换为(exit 1)
、ls fake_file
、kill <non-existent PID>
等都按预期工作。 此外,在本地运行时(不通过ssh
),这些匹配按预期。
问题似乎是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
命令都会自杀)。 但是,如果从子外壳运行,则该逻辑将失败:
$ 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
.