Bash 命令在终端运行,但不在 Jenkins/Bash 脚本中运行

Bash 命令在终端运行,但不在 Jenkins/Bash 脚本中运行

我正在使用 Jenkins 构建 HTML 文档并将其部署到本地 Apache Web 服务器,供我们的开发人员使用。当我在终端中运行命令时,一切都安装正确(证明服务器设置正确)。但是,当在 Jenkins 中运行相同的命令时,它们会被调用但没有任何变化。它不会删除html.zip(第 18 行),不会将文件移动到/var/html/www/subdir,也不会报告curl请求失败之外的任何错误。我有点不知道我做错了什么。

我应该注意,我将整个脚本称为sudo。我知道这不安全,但我想我会先尝试让脚本运行,然后再进行更改。为了确保user安装文档时不会遇到问题,我暂时允许它以 sudo 身份运行任何命令而无需密码。同样,我知道这不安全,但本着试图消除变量的精神,我添加了这个。

詹金斯这样调用这个脚本: sudo ./documentation-publisher.sh

目前,该脚本的权限限制最少,为 777。调用ls -l该脚本会报告: -rwxrwxrwx 1 devop developers 1144 Dec 3 10:29 documentation-publisher.sh

我尝试了这个帖子关于在脚本中明确设置路径,但没有发现任何差异。每个命令的明确路径也不会改变行为。

#!/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 

我可能做错了什么?

答案1

看起来您想要ssh进入 my.host.example.com,然后让脚本的其余部分在该主机上运行。如果是这种情况,您需要将脚本的其余部分作为输入传递给命令ssh;现在,它ssh从脚本的标准输入中获取输入,该标准输入可能为空,因此它会打开一个远程 shell 会话,向其发送文件结束,从而关闭会话ssh并在本地执行脚本的其余部分。为了远程运行这些命令,您需要将它们作为输入传递给命令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 然后将其替换为...哎呀,什么都没有)。您可以对每个命令的退出状态运行错误检查,例如:

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选项让它退出脚本,如果任何命令失败。此选项可让您不必逐个检查每个命令的错误,但不会提供有用的错误消息,并且如果无关紧要的事情由于某种原因返回错误状态,则可能会因退出脚本而导致麻烦(请参阅Bash常见问题解答#105了解为什么会导致意外行为的一些示例-e)。另外,如果您确实选择此选项,请确保set -e在脚本开头使用两者(或-xe在 shebang 行上使用),添加set -e作为发送到远程计算机的第一个命令。

顺便说一句,cd第 4 行的命令特别容易失败,因为它使用了相对路径。这意味着它尝试访问的目录cd取决于脚本启动的工作目录。请注意,这不一定是脚本所在的目录,它是从启动脚本的进程继承而来的,因此几乎可以是任何目录。Jenkins 可能使用与您不同的工作目录启动脚本,从而导致它一开始就失败。好吧,实际上不是失败,只是在错误的目录中运行所有剩余的命令(并且由于输入问题ssh,在错误的主机上)。

答案2

复制、删除或移动文件时,请修改脚本以使用绝对路径。目前您有以下几行

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

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

相关内容