Shellscript 抛出错误但不知何故仍在工作
Shellscript throws errors but somehow is still working
我有这个 shellscrip 可以在另一台机器上部署来自 travis 的代码。
#!/bin/sh
codecov
function sshDeploy {
printf -v __ %q ""
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 个 problems/question:
为什么会抛出这些错误,我怎样才能使这个 shellscript 尽可能独立于平台?我不知道哪个 buildagent 运行ning 我的脚本所以它应该 运行 在常见的 unix 系统上。
如果无法确保 travis 构建失败,我如何确保脚本 returns 的错误代码不同于 0。目前它仍然返回一个绿色构建,并且应用程序以某种方式启动,正如您在日志中看到的那样...
(3.) 有没有办法以比长字符串更好的方式格式化通过 ssh 发送的命令?
将其更改为 bash 脚本。
第一行:#!/bin/bash。
sh
$ printf -v ___ %q ""
sh: 1: printf: Illegal option -v
bash
$ printf -v ___ %q ""
<no error>
抛出错误是因为 function
关键字和 printf
的 -v
参数不被远程主机上的 /bin/sh
理解。
将 shebang 行更改为 #!/bin/bash
将修复这些错误。
即使出现上述错误脚本仍然 "works" 的原因(引号是因为我不认为它没有真正工作)是因为你很幸运。 /bin/sh
不理解 function
关键字,因此它完全忽略了该行,这意味着它可能 运行 ssh 命令直接(不是通过函数调用)并且没有使用 $__
正确(因为 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"
而且你甚至可以避免 printf -v
最有可能因为 git 引用不太可能(如果不是不能)包含任何 shell 元字符,这些元字符在 [= =43=] 那样的字符串(我至少相信)。如果您不介意 bash
要求,这肯定更安全。
我有这个 shellscrip 可以在另一台机器上部署来自 travis 的代码。
#!/bin/sh
codecov
function sshDeploy {
printf -v __ %q ""
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 个 problems/question:
为什么会抛出这些错误,我怎样才能使这个 shellscript 尽可能独立于平台?我不知道哪个 buildagent 运行ning 我的脚本所以它应该 运行 在常见的 unix 系统上。
如果无法确保 travis 构建失败,我如何确保脚本 returns 的错误代码不同于 0。目前它仍然返回一个绿色构建,并且应用程序以某种方式启动,正如您在日志中看到的那样...
(3.) 有没有办法以比长字符串更好的方式格式化通过 ssh 发送的命令?
将其更改为 bash 脚本。 第一行:#!/bin/bash。
sh
$ printf -v ___ %q ""
sh: 1: printf: Illegal option -v
bash
$ printf -v ___ %q ""
<no error>
抛出错误是因为 function
关键字和 printf
的 -v
参数不被远程主机上的 /bin/sh
理解。
将 shebang 行更改为 #!/bin/bash
将修复这些错误。
即使出现上述错误脚本仍然 "works" 的原因(引号是因为我不认为它没有真正工作)是因为你很幸运。 /bin/sh
不理解 function
关键字,因此它完全忽略了该行,这意味着它可能 运行 ssh 命令直接(不是通过函数调用)并且没有使用 $__
正确(因为 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"
而且你甚至可以避免 printf -v
最有可能因为 git 引用不太可能(如果不是不能)包含任何 shell 元字符,这些元字符在 [= =43=] 那样的字符串(我至少相信)。如果您不介意 bash
要求,这肯定更安全。