在Jenkins管道shell中运行嵌套命令

在Jenkins管道shell中运行嵌套命令,shell,jenkins,jenkins-pipeline,Shell,Jenkins,Jenkins Pipeline,我想在Jenkins管道中运行嵌套的shell命令,例如: docker stop $(docker ps -aq) 不幸的是,当我将其格式化为管道语法时: sh('docker stop $(docker ps -aq)') Jenkins似乎没有正确运行它们,但输出: “docker stop”至少需要1个参数。 我尝试在bash下运行命令,如下所述: 但最终会出现类似的问题。有什么办法解决这个问题吗?你有没有尝试过这样的想法: docker stop `docker ps -aq`

我想在Jenkins管道中运行嵌套的shell命令,例如:

docker stop $(docker ps -aq)
不幸的是,当我将其格式化为管道语法时:

sh('docker stop $(docker ps -aq)')
Jenkins似乎没有正确运行它们,但输出:

“docker stop”至少需要1个参数。

我尝试在bash下运行命令,如下所述:
但最终会出现类似的问题。有什么办法解决这个问题吗?

你有没有尝试过这样的想法:

docker stop `docker ps -aq`

如果将shell命令展开为两行,Jenkins管道将更容易执行此操作:

  • 第一个捕获要停止的Docker容器
  • 第二个命令用于停止在第一个命令中捕获的Docker容器
我们使用第一行将shell命令的输出捕获到变量中:

containers=sh(returnStdout:true,脚本:'sudo/usr/bin/docker ps-aq')

然后,我们使用第二个命令对存储在变量中的第一个命令的捕获输出进行操作:

sh(“sudo/usr/bin/docker stop$containers”)

请注意,
docker
命令通常适合使用
docker ps-aq
的输出来操作其其他命令,但如果它不喜欢存储在变量中的输出,可以按如下方式重新格式化它:

containers=sh(returnStdout:true,脚本:'sudo/usr/bin/docker ps-aq')。trim()

例如,这将去掉前导空格和尾随换行符。Docker CLI通常不关心这一点,但此处可能需要进行一些重新格式化

因为删除这里的换行符会导致一个长的组合容器ID,所以我们需要(正如您所指出的)用空格替换它来分隔容器ID。这将使存储在
容器中的字符串的格式设置成为
变量:


containers=sh(returnStdout:true,脚本:'sudo/usr/bin/docker ps-aq').replaceAll(“\n”,”)

我没有以这种方式使用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
        '''
    }
...

除了@Matt的答案

你需要检查一下空集装箱。如果没有可停止的容器,Jenkins build将失败并抛出以下错误消息

“docker stop”至少需要1个参数。

要处理这个问题,只需检查容器的可用性。这是完整的代码

stage('Clean docker containers'){
台阶{
剧本{
def doc_containers=sh(returnStdout:true,脚本:'docker container ps-aq')。replaceAll(“\n”,”)
if(文件容器){
sh“docker stop${doc_containers}”
}
}
}
}

您是否同意将这一行扩展为两行的解决方案?我也同意,谢谢Matt的建议。我觉得Jenkins将命令的输出作为命令运行。我得到以下错误:
[build abc pipeline TEST]运行shell脚本+docker ps-aq[pipeline]sh[build abc pipeline TEST]运行shell脚本+docker stop b21b1d2a85a2 b21b1d2a85a2+4c8e17511fd1/var/lib/jenkins/workspace/abc-TEST@tmp/durable-27835dc3/script.sh:第3行:4c8e17511fd1:未找到命令
看起来像输出(货柜编号)是以shell命令的形式运行的吗?@MaksimLuzik所以它可以工作,这很好,但是关于格式的警告似乎是正确的,所以你需要遵循我的建议。你是对的,Matt,因为
docker ps-aq
将每个容器ID作为自己的行返回,Jenkins从第二行开始以命令的形式运行ID。我不得不用空格t替换新行o使其正常工作,如下所示:
docker ps-aq | tr“\n”“”
@MaksimLuzik,因此它看起来像
。trim()
将是一个问题,因为它只删除换行符,不插入空格,这将导致一个长组合的容器ID,这将没有任何帮助。
.replaceAll(“\n-”)
最终将成为您的固有选择。请稍后更新答案。