我很难强制 wget 命令等到下载完成,问题发生在 Jenkins 内部sh '''script place '''
。我已将脚本编写在.sh
文件中,它运行时没有任何问题,但将其移至 Jenkins 后,Jenkins 中的其他命令会在下载完成之前执行。
我正在使用的脚本看起来像这样
sh '''
ssh -i "${keyfile}" -v -o StrictHostKeyChecking=no myuser@myVM << ENDSSH
cd /toFolder
ls -l
echo
if [ -f *.zip ]
then
echo "zip file already exists. Aborting"
exit 1
fi
wget ${URL}
sleep 1
export ZIP_FILENAME=`ls *.zip`
echo run: deployment.sh -j $ZIP_FILENAME
echo
deployment.sh -j $ZIP_FILENAME
ENDSSH
'''
为了将此代码粘贴到此处,我已移动ENDSSH
到部署脚本下的最后一行,以将其保留在代码块内。 (我知道它应该在脚本的最左边)
所以我的问题是在下载完成之前找到必须使用deployment.sh部署的文件名。
尝试使用wait
command 以及sleep
,我认为这不是最好的方法,但 wait 命令根本不等待,并且 sleep 命令有时会起作用。 curl
行为完全相同。只要我在 Linux 脚本方面没有足够的知识,任何建议都会非常感激。
答案1
如果您不wget
向后台发送(或任何命令),则 shell 会等待该命令完成,并且不会提前启动下一个命令。这就是 shell 的工作原理。我认为你真正的问题是 URL 和缺乏引用。如果 URL 包含一些可以欺骗您的 shell 的特殊字符,例如您可以运行如下所示的命令:
wget http://example.com&arg=1
其中包含&
char,因此将在后台启动 wget(带有截断的 URL),以防止使用引号:
wget "http://example.com&arg=1"
在您的代码中使用变量:
wget "${URL}"
答案2
<< ENDSSH
这里发生的情况是,在执行代码之前对反引号中的命令进行了评估。这是正确的行为(即使不是预期的!),因为定界符被视为双引号字符串。
例如,如果在运行代码之前没有 zip 文件,则ls *.zip
在运行heredoc代码之前将计算为空字符串,并且在执行时此行将保留ZIP_FILENAME
为空:
ZIP_FILENAME=`ls *.zip`
解决方案是用单引号引用heredoc标签,以便在执行之前不会计算heredoc中的任何表达式:
ssh ... << 'ENDSSH'
...
ENDSSH
答案3
我自己找到了解决方案,似乎脚本行的ENDSSH
dos 调用中的脚本,将下面的任何内容移动到另一个解决了问题。async
wget
ENDSSH
sh '''
ssh -i "${keyfile}" -v -o StrictHostKeyChecking=no myuser@myVM << ENDSSH
cd /toFolder
ls -l
echo
if [ -f *.zip ]
then
echo "zip file already exists. Aborting"
exit 1
fi
wget ${URL}
ENDSSH
'''
sh '''
ssh -i "${keyfile}" -v -o StrictHostKeyChecking=no myuser@myVM << ENDSSH2
export ZIP_FILENAME=`ls *.zip`
echo run: deployment.sh -j $ZIP_FILENAME
echo
deployment.sh -j $ZIP_FILENAME
ENDSSH2
'''
不是最好和最干净的解决方案,但也许这可以帮助面临同样问题的人。