为什么 运行 "pkill -f <anything>" over ssh 仅在其结果分支时失败?
Why does running "pkill -f <anything>" over ssh fail only when branching on its result?
发现 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
只是意味着 "an error occurred"(超级有用)。
用 (exit 1)
、ls fake_file
、kill <non-existent PID>
等替换 pkill
命令,一切都按预期工作。此外,当 运行 在本地(而不是通过 ssh
)时,这些匹配符合预期。
问题似乎是 pkill
正在自杀。或者更确切地说,它正在杀死拥有它的 shell。
首先,ssh
似乎使用远程用户的 shell 来执行某些 "complicated" 命令:
$ 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
周围的一些代码,这样我就可以避免使用 "complicated" 远程命令。理论上我认为你也可以做类似 pgrep -f <cmd> | grep -v $$ | xargs kill
.
的事情
发现 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
只是意味着 "an error occurred"(超级有用)。
用 (exit 1)
、ls fake_file
、kill <non-existent PID>
等替换 pkill
命令,一切都按预期工作。此外,当 运行 在本地(而不是通过 ssh
)时,这些匹配符合预期。
问题似乎是 pkill
正在自杀。或者更确切地说,它正在杀死拥有它的 shell。
首先,ssh
似乎使用远程用户的 shell 来执行某些 "complicated" 命令:
$ 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
周围的一些代码,这样我就可以避免使用 "complicated" 远程命令。理论上我认为你也可以做类似 pgrep -f <cmd> | grep -v $$ | xargs kill
.