当我想要执行多个 shell 命令时脚本化管道返回第一个命令的答案而不执行管道。这是我的情况:我想获取 HTML 页面上的特定内容。所以我在页面上做了一个curl,然后是grep,最后是awk。
def checkState(hostUri, check) {
node('master') {
def result = sh 'curl -Lsd "login=username&password=password&button=Login" -c cookie ${hostUri} && grep ${check} && awk -F \'"\' {\'print $2\'}'
println result
}
只有我的管道的控制台返回对应于仅执行curl命令而不执行grep和awk。
Running on Jenkins in /var/lib/jenkins/workspace/Clearcase@8
[Pipeline] {
[Pipeline] sh
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
...
</html>
[Pipeline] }
[Pipeline] // node
我尝试了不同的方法,例如使用脚本化管道中不存在的命令'''
。new BuildProcess
答案1
在所示的 Jenkinsfile 中,变量赋值涉及 shell 步骤:
def result = sh 'curl -Lsd "login=username&password=password&button=Login" -c cookie ${hostUri} && grep ${check} && awk -F \'"\' {\'print $2\'}'
Jenkins 此时将调用 shell,并将以下命令传递给它:
curl -Lsd "login=username&password=password&button=Login" -c cookie ${hostUri} && grep ${check} && awk -F '"' {'print $2'}
运算&&
符表示 AND 列表。在这种情况下,如果curl
命令成功,则grep
执行该命令;如果成功,则将awk
执行该命令。这些命令的标准输入/输出/错误流彼此不连接。
由于此处的目的是解析curl
使用grep
andawk
语句的输出,因此应使用管道而不是&&
运算符:
def result = sh 'curl -Lsd "login=username&password=password&button=Login" -c cookie ${hostUri} | grep ${check} | awk -F \'"\' {\'print $2\'}'
还请考虑引用hostUri
&check
变量,以防这些字段中出现特殊字符。
最后一点:如果没有文件名参数或某种输入,命令grep ${check}
&在技术上是不完整的。awk -F '"' {'print $2'}
如果您从 shell 终端按原样运行它们,它们就会卡住。然而,由于 Jenkins 以非交互方式运行构建过程,我假设它们的标准输入流是从/dev/null
.在这种情况下,grep
命令将失败并显示非零错误代码。