使用“curl | bash”远程执行脚本反馈

使用“curl | bash”远程执行脚本反馈

我正在一个使用大量此类命令的平台上工作: ssh [email protected] 'curl http://some_server/script.sh | bash'

这对于远程执行脚本来说确实非常简洁和方便,但是,我看不到获取脚本输出/退出代码的方法。任何人都可以想出一些办法来确保脚本已正确执行(从启动 ssh 的主机的角度来看)。

答案1

正如 @Zoredache 指出的那样,ssh将远程命令的状态作为其自己的退出状态进行中继,因此错误检测可以通过 SSH 透明地进行。但是,您的示例中有两个重要点需要特别考虑。

首先,curl它往往非常宽容,将许多异常情况视为成功。例如,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。

其次,你有一个管道,这意味着第一个或第二个命令都可能发生故障。从关于bash 中的管道(1)

管道的返回状态是最后一个命令的退出状态,除非pipefail启用了该选项(请参阅内置集合)。如果pipefail启用,管道的返回状态是最后一个(最右边)以非零状态退出的命令的值,如果所有命令都成功退出,则返回零。

附注:bash文档之所以相关,不是因为您通过管道连接到bash,而是因为(我假设)它是您的远程用户的登录 shell,因此是解释远程命令行并处理管道执行的程序。如果用户有不同的登录 shell,请参阅该 shell 的文档。

举个具体的例子,

( echo whoami ; false ) | bash
echo $?

输出结果

login
0

说明bash管道末端的 会屏蔽 返回的错误状态 ,false只要 成功执行 就会返回0 whoami

相比之下,

set -o pipefail
( echo whoami ; false ) | bash
echo $?

产量

login
1

以便报告管道前半部分出现故障。


综上所述,解决方案应该是

ssh [email protected] 'set -s pipefail ; curl -fsS http://some_server/script.sh | bash'

这样,如果以下任何一个返回非零,您将获得非零的退出状态:

  • ssh
  • 远程登录 shell
  • curl
  • bash管道末端

此外,如果curl -fsS检测到异常的 HTTP 状态代码,那么它将:

  • 抑制其 STDOUT,这样就不会有任何内容通过管道传输bash到执行
  • 返回一个非零值,该值被正确传播
  • 将一行诊断消息打印到其 STDERR,该消息也会一直传播

答案2

那真是太糟糕了。如果您想要远程执行,请使用可以正确执行远程执行的工具,例如 func 或 mcollective。

答案3

当 SSH 返回时,它应该从脚本发出退出代码。

尝试一下。您应该会看到返回ssh user@host 'echo "exit 2" | bash' ; echo $?的值。2

只需在脚本中写入大量良好的错误检查,并确保脚本退出时出现有用的错误和退出代码。确保您的脚本对任何错误返回非零退出代码。

答案4

这里有几个您可以尝试的选项。

另一种方法是让 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 所建议的,在脚本中添加多个退出状态将有助于您识别出了什么问题。

相关内容