我正在使用很多这样的命令的平台: ssh [email protected] 'curl http://some_server/script.sh | bash' ssh [email protected] 'curl http://some_server/script.sh | bash'
这对于远程执行脚本来说是非常干净和方便的,但是,我还是看不到脚本的输出/退出代码。 任何人都可以弄清楚一些事情,以确保脚本已经正确执行(从主机启动ssh的angular度来看)。
正如@Zoredache所指出的那样, ssh将远程命令的状态作为自己的退出状态进行中继,所以错误检测在SSH上透明地工作。 但是,在你的例子中,需要特别考虑两点。
首先, curl往往是非常宽松的,对待许多exception情况的成功。 例如, curl http://serverfault.com/some-non-existent-url-that-returns-404实际上有一个退出状态0.我觉得这种行为是违反直觉的。 要将这些情况视为错误,我喜欢使用-fsS标志:
--fail标志会禁止输出,这样bash就不会有机会像执行代码一样执行Web服务器的404错误页面。 --silent --show-error标志一起提供了合理数量的错误报告。 --silent压制curl所有评论。 --show-error重新启用发送到STDERR的错误消息。 其次,你有一个pipe道,这意味着在第一个或第二个命令中可能发生故障。 关于bash(1)中的pipe道部分:
pipe道的返回状态是最后一个命令的退出状态,除非
pipefail选项被启用(参见Set Builtin )。 如果启用pipefail,则pipe道的返回状态是以非零状态退出的最后一个(最右边的)命令的值,如果所有命令均成功退出,则为零。
注意: bash文档是相关的,不是因为你pipe到bash ,而是因为(我认为)它是你的远程用户的loginshell,因此是解释远程命令行并处理pipe道执行的程序。 如果用户有不同的loginshell,请参阅该shell的文档。
作为一个具体的例子,
( echo whoami ; false ) | bash echo $?
产生输出
login 0
certificatepipe道末端的bash将掩盖false返回的错误状态。 只要成功执行whoami ,它将返回0。
相反,
set -o pipefail ( echo whoami ; false ) | bash echo $?
产量
login 1
以便报告上半年的pipe道故障。
把它放在一起,那么解决scheme应该是
ssh [email protected] 'set -s pipefail ; curl -fsS http://some_server/script.sh | bash'
这样,如果以下任何一个返回非零,您将获得一个非零的退出状态:
ssh curl bash 而且,如果curl -fsS检测到一个exception的HTTP状态码,那么它将会:
bash被执行 这是一个可怕的黑客。 如果你想远程执行,使用远程执行的东西,如func或mcollective。
这一切都取决于script.sh的function。 如果它是详细的(做输出的东西),你应该能够在你的sshstream中的STDOUT / STDERR上看到它们。 如果如果不修改它这样做。
当SSH返回时,它应该从脚本中发出退出代码。
尝试ssh user@host 'echo "exit 2" | bash' ; echo $? ssh user@host 'echo "exit 2" | bash' ; echo $? 。 你应该看到返回值2 。
只需在脚本中写好很多错误检查,并确保脚本退出时有一个有用的错误,并退出代码。 确保您的脚本返回任何错误的非零退出代码。
这里有几个选项,你可以尝试。
另一种方法将是有echo $? 在脚本执行之后运行,
# ssh [email protected] 'curl http://some_server/script.sh | bash; echo $?'
这会给你脚本的退出状态。 或退出状态为0时仅提供文本
# ssh [email protected] 'curl http://some_server/script.sh | bash && echo "Script Completed!"'
这将显示“脚本完成!” 成功执行。 或退出状态不为0时,仅显示错误代码
# ssh [email protected] 'curl http://some_server/script.sh | bash || echo "Script Failed: $?"'
这将显示“脚本失败:”正如@Zoredache所build议的,添加多个退出状态到你的脚本将帮助你识别出错的地方。