Bash命令在terminal运行,但不能在Jenkins / Bash脚本中运行

我正在使用Jenkins构buildHTML文档并将其部署到本地Apache Web服务器供我们的开发人员使用。 当我在terminal中运行命令时,一切安装正确(certificate服务器安装正确)。 但是,当从Jenkins中运行相同的命令时,它们会被调用,但没有任何更改。 它不会删除html.zip (第18行),不会将文件移动到/var/html/www/subdir ,并且不会报告curl请求失败之外的任何错误。 我有点失落,因为我做错了什么。

我应该注意到,我把这个脚本叫做sudo 。 我知道这是不安全的,但我想我会尝试让脚本先工作,然后再改变。 为了确保user不会遇到安装文档的问题,我暂时允许它运行任何命令作为sudo没有密码。 再次,我知道这是不安全的,但本着试图消除variables的精神,我加了这个。

Jenkins像这样调用这个脚本: sudo ./documentation-publisher.sh

对脚本的权限是现在最less的限制,777.在脚本报告中调用ls -l-rwxrwxrwx 1 devop developers 1144 Dec 3 10:29 documentation-publisher.sh

我试图从这个post的build议明确设置脚本的path,但没有注意到任何差异。 每个使用的命令的显式path也不会改变行为。

 #!/bin/sh -x echo "Archiving generated HTML for transfer..." cd Example/docs/html/ zip -r html.zip ./ scp -i ~/.ssh/id_rsa html.zip [email protected]:/home/user ssh -i ~/.ssh/id_rsa [email protected] echo "Extracting generated HTML into www directory..." PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games unzip -o html.zip -d ./subdir rm -r /var/www/html/subdir mkdir /var/www/html/subdir cp -r ./subdir/* /var/www/html/subdir/ echo "Cleaning up after file transfer..." rm -rf ./subdir rm ./html.zip echo "Testing install..." curl -f my.host.example.com/subdir/index.html exit 

我可能做错了什么?

它看起来像你想ssh进入my.host.example.com,然后让脚本的其余部分在该主机上运行。 如果是这种情况,则需要将脚本的其余部分作为input传递给ssh命令; 就像现在一样, ssh正在从脚本的stdin中input内容,这可能是空的,所以它打开一个远程shell会话,发送一个文件结束,closuresssh会话并在本地执行脚本的其余部分。 为了远程运行这些命令,您需要将它们作为input传递给ssh命令,如下所示:

 ssh -i ~/.ssh/id_rsa [email protected] <<EOF echo "Extracting generated HTML into www directory..." PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games [...] exit EOF 

其次,脚本没有错误检查。 一般来说,在脚本中查看每个命令是个好主意,然后问自己如果失败会发生什么。 如果脚本的其余部分继续下去,还是会“跑掉”,做一些傻事? 例如,如果scp命令失败(无论出于何种原因),那么运行脚本的其余部分就没有任何意义了(可能会破坏/ var / www / html / subdir,然后replace它与…哎呀,什么都没有)。 你可以对每个命令的退出状态进行错误检查,例如:

 scp -i ~/.ssh/id_rsa html.zip [email protected]:/home/user || { echo "Failed to scp the html files to my.host.example.com." >&2 exit 1 } 

…或者使用shell的-e选项使任何命令失败时退出脚本。 这个选项不需要单独错误检查每个命令,但是不会提供信息性错误信息,并且如果出于某种原因返回错误状态,则退出脚本可能会导致问题(请参阅BashFAQ#105为什么-e可能会导致意外的行为的一些例子)。 另外,如果你使用这个选项,确保在脚本的开始处使用set -e (或在shebang行使用-xe ),并将set -e添加为发送到远程计算机的第一个命令。

顺便说一下,第4行的cd命令很可能会失败,因为它使用相对path。 这意味着它尝试cd的目录取决于脚本从哪个工作目录开始。 请注意,这不一定是脚本所在的目录,它是从启动脚本的进程inheritance的,因此几乎可以是任何东西。 jenkins可能会用不同的工作目录来启动脚本,从而导致脚本无法正常工作。 那么,没有真正的失败,只需要运行所有剩余的命令在错误的目录(因为sshinput问题,在错误的主机上)。

当您复制,删除或移动文件时,请修改脚本以使用绝对path。 目前你有这些线

rm ./html.zip cp -r ./subdir/* /var/www/html/subdir/

./部分更改为该文件或目录的完整path。