我试图使用Jenkins创建一个特殊的git存储库。我创建了一个只执行shell脚本的自由风格项目。当我手动执行这个脚本,没有Jenkins时,它运行得很好。 然而,从詹金斯来看,它的表现完全不同。
# this will remove all subtrees
git log | grep git-subtree-dir | tr -d ' ' | cut -d ":" -f2 | sort | uniq | xargs -I {} bash -c 'if [ -d $(git rev-parse --show-toplevel)/{} ] ; then rm -rf {}; fi'
rm -rf .git
如果这部分由Jenkins执行,在控制台输出中我会看到这种错误:
rm: cannot remove '.git/objects/pack/pack-022eb85d38a41e66ad3f43a5f28809a5a3ee4a0f.pack': Device or resource busy
rm: cannot remove '.git/objects/pack/pack-05630eb059838f149ad30483bd48d37f9a629c70.pack': Device or resource busy
rm: cannot remove '.git/objects/pack/pack-26f510b5a2d15ba9372cf0a89628d743811e3bb2.pack': Device or resource busy
rm: cannot remove '.git/objects/pack/pack-33d276d82226c201eedd419e5fd24b6b906d4c03.pack': Device or resource busy
我修改了这部分脚本:
while true
do
if rm -rf .git ; then
break
else
continue
fi
done
但这并没有帮助。在任务管理器中,我看到一个不会终止的git进程。 我通过大量的谷歌搜索来形容这个剧本,我不太了解会发生什么。
Jenkins在IIS后面的Windows Server 2012上运行; shell脚本由git for Windows附带的bash执行。
答案 0 :(得分:0)
1 /确保您的路径正确,并且在jenkins工作开始的过程中没有报价/双引号转义。
2 /您的命令行有点太方便,无法正确安全地进行评估。
将命令放在常规脚本中,从#!/bin/bash
开始,而不是通过命令行。
xargs -I {} bash -c 'if [ -d $(git rev-parse --show-toplevel)/{} ] ; then rm -rf {}; fi'
becames
xargs -I {} /path/myscript.sh {}
与
#!/bin/bash
rev-parse="$(git rev-parse --show-toplevel)"
wait
if [ -d ${rev-parse}/${1} ] ; then
rm -rf ${1}
fi
请注意,您的脚本确实不安全,因为rm -rf
参数之前甚至没有评估它......!
3 /您可以在wait
和git
之间添加rm
以等待git进程结束
4 /将您的git命令记录到日志文件中,重定向为>> /tmp/git-jenkins-log
答案 1 :(得分:0)
以下是rm -rf
失败的无限循环
while true
do
if rm -rf .git ; then
break
else
continue
fi
done
确实可以在continue
或for
循环中使用while
来获取下一个条目,但在此while循环中,它将永远运行相同的rm
命令。
答案 2 :(得分:0)
嗯,通过运行来自不同用户的脚本,我能够解决我的问题。
默认情况下,Windows Jenkins从用户SYSTEM执行所有作业。我不知道为什么它会影响我的脚本的行为,但是使用psexec
从专门创建的用户帐户运行它。
如果有人感兴趣,我做了类似的事情:
psexec -accepteula -h -user Jenkins -p _password_ "full/path/to/bash.exe" full/path/to/script.sh