【问题标题】:Run loop command inside shell in groovy在 groovy 中的 shell 内运行循环命令
【发布时间】:2018-12-04 12:25:20
【问题描述】:

我使用以下命令按预期工作

def before(Map<String, String> params) {
  sh """

  make ${params.get('arg')}
  """
}

现在我需要对其进行一些修改以使用循环运行,我得到 complication error

def before(Map<String, String> params) {
  sh """

  params.each{ k, v -> make ${v} }
  """
}

知道如何解决这个问题吗?我尝试添加{ } 没有成功

【问题讨论】:

    标签: bash shell jenkins groovy


    【解决方案1】:

    您会看到编译错误,因为您传递给sh 步骤的字符串主体包含 bash 无法识别的部分(这部分:params.each{ k, v -&gt; make ${v} })。

    您可以从不同的角度解决此问题:您可以将所有映射条目收集到make ${arg} 命令列表中,并且可以在使用换行符\n 加入所有命令后将其传递给sh 步骤。考虑以下示例:

    def before(Map<String, String> map) {
        sh(map.collect { k,v -> "make ${v}" }.join("\n"))
    }
    
    before([arg1: "foo", arg2: "bar"])
    

    sh 步骤中执行的代码相当于这样:

    sh """
        make foo
        make bar
    """
    

    更新:在 """ 块内执行多​​个命令

    如果您想在 """ 块中应用前面显示的解决方案,您可以尝试使用类似这样的东西:

    def before(Map<String, String> map) {
        sh """
    
        # Run any command beforehand 
    
        ${map.collect { k,v -> "make ${v}" }.join(" && ")}
        """
    }
    

    这种方法将允许您在执行一系列命令之前放置任何 bash 命令,例如

    make foo && make bar && make 123 
    

    您可以使用与&amp;&amp; 不同的连接器(例如,\n,如上例所示)。但是,使用&amp;&amp; 链接命令可能会更好,因为如果其中一个失败,它将阻止下一个命令运行。

    【讨论】:

    • 谢谢,我已经像您的示例一样尝试过,但出现错误Also: groovy.lang.MissingPropertyException: No such property: v for class: groovy.lang.Binding
    • @shopiaT 尝试使用与params 不同的参数名称(例如map)。听起来 Jenkins 管道选择了一个全局 params 变量或类似的东西。
    • @shopiaT 我在自己的 Jenkins 管道中运行此示例 - 命名参数 paramsmap 没有任何区别,两者都按预期工作。我确实检查了声明性管道以及脚本化管道,结果相同。您的异常建议您传递 groovy.lang.Binding 对象而不是 Map
    • 我尝试将名称更改为map,但仍然是同样的问题,您是否像sh """ map.collect { k,v -&gt; "make ${v}" }.join("\\n") """一样使用它?
    • 这适合你吗?我的意思是在函数中?
    猜你喜欢
    • 2014-11-03
    • 1970-01-01
    • 2010-09-14
    • 2016-04-02
    • 1970-01-01
    • 2014-06-15
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多