我想在Jenkins管道中运行嵌套的shell命令,例如:
docker stop $(docker ps -aq)
不幸的是,当我将其格式化为管道语法时:
sh('docker stop $(docker ps -aq)')
Jenkins似乎没有正确运行它们,但输出:
"docker stop" requires at least 1 argument(s).
我尝试在bash下运行命令,就像告诉这里: Run bash command on jenkins pipeline 但最终遇到了类似的问题。任何想法如何解决这个问题?
答案 0 :(得分:4)
如果将shell命令扩展为两行,则Jenkins Pipeline会变得更容易:
我们使用第一行将shell命令的输出捕获到变量中:
containers = sh(returnStdout: true, script: 'sudo /usr/bin/docker ps -aq')
然后我们使用第二个命令对存储在变量中的第一个命令的捕获输出进行操作:
sh("sudo /usr/bin/docker stop $containers")
请注意,docker
命令通常适合docker ps -aq
的输出以便使用其他命令进行操作,但如果它不喜欢存储在变量中的输出,则可以像下面那样重新格式化它:
containers = sh(returnStdout: true, script: 'sudo /usr/bin/docker ps -aq').trim()
由于在此处删除换行符会导致一个长的组合容器ID,我们需要(如您所述)将其替换为空格以分隔容器ID。这将使字符串的格式存储在containers
变量中:
containers = sh(returnStdout: true, script: 'sudo /usr/bin/docker ps -aq').replaceAll("\n", " ")
答案 1 :(得分:1)
我没有以这种方式使用docker stop命令,但是docker rm命令的语法相同。管道代码块+ OP的行,例如:
...
withEnv(["port=$port", "user=$user", "env=$env"]) {
sh '''
ssh -p $port $user@$env docker rm \$(docker ps -aq) || true; \
ssh -p $port $user@$env docker rmi \$(docker images -aq) || true; \
ssh -p $port $user@$env docker stop \$(docker ps -aq) || true
'''
}
...
答案 2 :(得分:1)
添加到@Matt 的回答中,
您需要检查空容器。如果没有可用的容器可以停止,Jenkins 构建将失败并抛出以下错误消息
"docker stop" requires at least 1 argument(s).
要解决这个问题,您只需要检查容器的可用性。这是完整的代码
stage('Clean docker containers'){
steps{
script{
def doc_containers = sh(returnStdout: true, script: 'docker container ps -aq').replaceAll("\n", " ")
if (doc_containers) {
sh "docker stop ${doc_containers}"
}
}
}
}
答案 3 :(得分:0)
你有没有试过像:
docker stop `docker ps -aq`