Jenkins Pipeline执行ssh命令报ENDSSH command not found如何解决
问题原因
-bash: line 6: ENDSSH: command not found 报错的核心是 Here Document(heredoc)的结束标记规则未被满足:bash 要求 heredoc 的结束标记必须顶格书写,前后不能存在任何空格、制表符等空白字符,否则就会被识别为普通命令执行,触发你遇到的报错。
解决方法
方案1:删除ENDSSH的前置缩进(最通用)
直接将代码中ENDSSH前的所有空白字符删掉,顶格书写即可,修改后代码如下:
stage("Checkout my-git-repo"){ steps { script { sh """ ssh -o StrictHostKeyChecking=accept-new -o LogLevel=ERROR -o UserKnownHostsFile=/dev/null -i ${JENKINS_KEY} ${JENKINS_KEY_USR}@${env.hostname} << ENDSSH echo 'Removing current /opt/my-git-repo directory' sudo rm -rf /opt/my-git-repo echo 'Cloning new my-git-repo repo into /opt' git clone ssh://${JENKINS_USR}@git.gitbox.com:30303/my-git-repo sudo mv /home/jenkins/my-git-repo /opt ENDSSH """ } } }
方案2:使用带减号的heredoc语法保留缩进
如果你需要保留代码的缩进格式,可以将heredoc标记改为<<- ENDSSH,该语法会自动忽略结束标记前的所有制表符(Tab),注意仅支持Tab缩进,不支持空格缩进:
stage("Checkout my-git-repo"){ steps { script { sh """ ssh -o StrictHostKeyChecking=accept-new -o LogLevel=ERROR -o UserKnownHostsFile=/dev/null -i ${JENKINS_KEY} ${JENKINS_KEY_USR}@${env.hostname} <<- ENDSSH echo 'Removing current /opt/my-git-repo directory' sudo rm -rf /opt/my-git-repo echo 'Cloning new my-git-repo repo into /opt' git clone ssh://${JENKINS_USR}@git.gitbox.com:30303/my-git-repo sudo mv /home/jenkins/my-git-repo /opt ENDSSH """ } } }
额外说明
你当前使用的无引号ENDSSH标记会让Jenkins先解析所有变量再传给远程服务器,如果你有变量需要在远程服务器侧解析,可以将标记改为<< 'ENDSSH',此时所有变量不会被Jenkins提前替换,会在远程主机执行时再解析。
内容的提问来源于stack exchange,提问作者Michael Giacomo
相关产品推荐
相关产品推荐

