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

bq9c1y66  于 2023-06-21  发布在  Jenkins
关注(0)|答案(5)|浏览(170)

我想在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但最终会出现类似的问题。有什么解决办法吗?

e5njpo68

e5njpo681#

如果您将shell命令扩展为两行,则Jenkins Pipeline会更容易:

  • 第一个捕获您想要停止的Docker容器。
  • 第二个命令用于停止第一个命令中捕获的Docker容器。

我们使用第一行将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()
例如,这将去掉前导空格和尾随换行符。Docker CLI通常不关心这一点,但在这里可能需要进行一些重新格式化。
由于删除这里的换行符会导致一个很长的组合容器ID,因此我们需要(如您所述)用空格替换它来分隔容器ID。这将使存储在containers变量中的字符串的格式:
containers = sh(returnStdout: true, script: 'sudo /usr/bin/docker ps -aq').replaceAll("\n", " ")

oyxsuwqo

oyxsuwqo2#

我还没有这样使用过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
        '''
    }
...
jucafojl

jucafojl3#

加上@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}"
                    }
                    
                }
            }
        }
qrjkbowd

qrjkbowd4#

你有没有试过像这样的:

docker stop `docker ps -aq`

7uzetpgm

7uzetpgm5#

stage('Some stage') {
                steps {
                    script{
                        def doc_containers = sh(returnStdout: true, script: 'docker container ps -aq').replaceAll("\n", " ") 
                        if (doc_containers) {
                            sh "docker rm -f ${doc_containers}"
                        }
                    }
                 }
              }

这在我的centos linux代理上很有效
注意:docker rm -f删除所有容器,即使它正在运行

相关问题