[英]Running nested commands in Jenkins pipeline shell
我想在 Jenkins 管道中像這樣運行嵌套的 shell 命令:
docker stop $(docker ps -aq)
不幸的是,當我將其格式化為管道語法時:
sh('docker stop $(docker ps -aq)')
詹金斯似乎沒有正確運行它們,但輸出:
"docker stop" requires at least 1 argument(s).
我試圖在 bash 下運行命令,就像這里所說的: 在 jenkins 管道上運行 bash 命令但最終遇到了類似的問題。 任何想法如何解決這個問題?
如果將 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()
例如,這將去除前導空格和尾隨換行符。 Docker CLI 通常不關心這個,但這里可能需要一些重新格式化。
由於刪除此處的換行符會導致組合容器 ID 過長,因此我們需要(如您所述)將其替換為空格以分隔容器 ID。 這將使存儲在containers
變量中的字符串格式化:
containers = sh(returnStdout: true, script: '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 構建將失敗並拋出以下錯誤消息
"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}"
}
}
}
}
你有沒有試過像這樣的想法:
docker stop `docker ps -aq`
?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.