Shellscript抛出错误,但不知何故仍然有效

时间:2015-02-03 15:22:05

标签: shell

我有这个shellscrip来从另一台机器上的travis部署代码。

#!/bin/sh
codecov
function sshDeploy {
    printf -v __ %q "$1"
    ssh -oStrictHostKeyChecking=no deployuser@178.62.252.23 "cd api; git pull origin master; git checkout $__;./sbt clean; ./sbt stage; ./neeedo restart; exit $?"
}
sshDeploy $TRAVIS_COMMIT
exit $?

此脚本在我的macbook上运行时没有任何错误。然而,当我在travis上运行它时(不幸的是我无法告诉你他们在构建器上运行的unix因为我没有直接访问它们),我观察到了奇怪的行为。

抛出错误但脚本仍以某种方式执行。

./after-success.sh: 3: ./after-success.sh: function: not found
./after-success.sh: 4: printf: Illegal option -v
Warning: Permanently added '178.62.252.23' (ECDSA) to the list of known hosts.
From https://github.com/HTW-Projekt-2014-Commercetools/api
 * branch            master     -> FETCH_HEAD
... Git Log ...
Stopping Neeedo-API: ..done.
Starting Neeedo-API: ....done.
./after-success.sh: 6: ./after-success.sh: Syntax error: "}" unexpected

现在我有2个问题/问题:

  1. 为什么会抛出这些错误,如何使这个shellcript尽可能独立于平台?我不知道哪个buildagent正在运行我的脚本,因此它应该在常见的unix系统上运行。

  2. 如果某些内容无法确保travis构建失败,如何确保脚本返回的错误代码不是0。目前它仍然返回绿色版本,并且应用程序以某种方式启动,您可以在日志中看到...

  3. (3。)有没有办法以比长字符串更好的方式格式化通过ssh发送的命令?

2 个答案:

答案 0 :(得分:2)

将其更改为bash脚本。 第一行:#!/ bin / bash。

<强> SH

$  printf -v ___ %q "$1"
sh: 1: printf: Illegal option -v

<强>的bash

$ printf -v ___ %q "$1"
<no error>

答案 1 :(得分:1)

由于远程主机上的function无法理解-v关键字和printf /bin/sh参数,因此会引发错误。

将shebang行更改为#!/bin/bash将修复这些错误。

脚本仍然工作的原因&#34;即使有上述错误(报价,因为它不是真的有效,我不认为)是因为你很幸运。 /bin/sh无法理解function关键字,因此它完全忽略了该行,这意味着它可能直接运行ssh命令(而不是通过函数调用)并且没有使用{ {1}}正确(由于$__错误)所以没有运行正确的printf -v命令。

我本来期望看到一个错误,即不知道git checkout命令是什么,但也许它没有做到这一点,或者它可能被其他东西隐藏了。

所有人都说,根本就没有这个功能的真正原因。

脚本的退出状态是最后一个运行命令的退出状态,因此无需以sshDeploy结束。

有了这个,没有这个功能你的脚本就变成了。

exit $?

你甚至可以避免使用codecov printf -v __ %q "$TRAVIS_COMMIT" ssh -oStrictHostKeyChecking=no deployuser@178.62.252.23 "cd api; git pull origin master; git checkout $__;./sbt clean; ./sbt stage; ./neeedo restart" ,因为git refs不太可能(如果不是无能为力)包含任何shell元字符,当在shell字符串中扩展时需要转义(我至少相信)。如果您不介意printf -v要求,这肯定会更安全。