由Jenkins运行的Shell脚本创建了非终止进程

时间:2018-01-10 09:49:29

标签: bash git jenkins

我试图使用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执行。

3 个答案:

答案 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 /您可以在waitgit之间添加rm以等待git进程结束

4 /将您的git命令记录到日志文件中,重定向为>> /tmp/git-jenkins-log

5 /将所有这些命令放在脚本中(参见#2)

答案 1 :(得分:0)

以下是rm -rf失败的无限循环

while true
do
    if rm -rf .git ; then
        break
    else
        continue
    fi
done

确实可以在continuefor循环中使用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