无法在Jenkins中的Groovy中运行shell命令

无法在Jenkins中的Groovy中运行shell命令,jenkins,groovy,jenkins-groovy,Jenkins,Groovy,Jenkins Groovy,我试图通过运行shell命令从从属服务器获取某些值,例如: git rev-parse HEAD git config --get remote.origin.url 我尝试为此编写的方法是: def executeCommand(String command) { stdout = sh script: command, returnStdout: true return stdout.trim() } 现在,当我尝试运行第一个命令时: output = executeCo

我试图通过运行shell命令从从属服务器获取某些值,例如:

git rev-parse HEAD
git config --get remote.origin.url
我尝试为此编写的方法是:

def executeCommand(String command) {
    stdout = sh script: command, returnStdout: true
    return stdout.trim()
}
现在,当我尝试运行第一个命令时:

output = executeCommand('git rev-parse HEAD')
我得到一个错误:

[Running] groovy "/Users/user-a/Documents/cmd.groovy"
Caught: groovy.lang.MissingMethodException: No signature of method: cmd.sh() is applicable for argument types: (LinkedHashMap) values: [[script:git rev-parse HEAD, returnStdout:true]]
Possible solutions: is(java.lang.Object), use([Ljava.lang.Object;), run(), run(), any(), tap(groovy.lang.Closure)
groovy.lang.MissingMethodException: No signature of method: cmd.sh() is applicable for argument types: (LinkedHashMap) values: [[script:git rev-parse HEAD, returnStdout:true]]
Possible solutions: is(java.lang.Object), use([Ljava.lang.Object;), run(), run(), any(), tap(groovy.lang.Closure)
    at cmd.executeCommand(cmd.groovy:2)
    at cmd.run(cmd.groovy:6)
我还尝试:

output = command.execute().text
但这不会带来任何回报

关于如何在Jenkins的Groovy中运行shell命令并记录输出,我已经没有什么想法了

更多详细信息

我与詹金斯共享图书馆合作。我已在中为我的
Jenkinsfile
公开了一个名为
getLatestBuildDetails()
的方法。此方法在我的库中定义。该方法中的一个操作是在本地执行
git
命令。因此,为了在本地运行任何shell命令,我创建了
executeCommand
函数,该函数将实际命令作为字符串运行,并执行它,然后返回输出供
getLatestBuildDetails()

稍后使用

编辑: 我会选择
execute()
或者我认为更好的。 运行
cmd.execute().text
时,我认为您没有得到任何输出,因为
.text
返回命令的标准输出,并且您的命令可能只使用标准错误作为其输出,您可以同时检查:

def process = cmd.execute()
def stdOut = process.inputStream.text
def stdErr = process.errorStream.text

库类不能直接调用sh或git之类的步骤。但是,它们可以在封闭类的范围之外实现方法,这些方法反过来调用管道步骤,例如:

// src/org/foo/Zot.groovy
package org.foo;

def checkOutFrom(repo) {
  git url: "git@github.com:jenkinsci/${repo}"
}

return this
然后可以从脚本化管道调用:

def z = new org.foo.Zot()
z.checkOutFrom(repo)
这种方法有局限性;例如,它阻止声明超类

或者,可以使用此函数将一组步骤显式传递给库类、构造函数或一个方法:

package org.foo
class Utilities implements Serializable {
  def steps
  Utilities(steps) {this.steps = steps}
  def mvn(args) {
    steps.sh "${steps.tool 'Maven'}/bin/mvn -o ${args}"
  }
}
在保存类的状态时,如上面所述,该类必须实现可序列化接口。这确保了使用该类的管道(如下面的示例所示)可以在Jenkins中正确地挂起和恢复

@Library('utils') import org.foo.Utilities
def utils = new Utilities(this)
node {
  utils.mvn 'clean package'
}
如果库需要访问全局变量,如env,则应以类似的方式将这些变量显式传递到库类或方法中

而不是将大量变量从脚本化管道传递到库中

package org.foo
class Utilities {
  static def mvn(script, args) {
    script.sh "${script.tool 'Maven'}/bin/mvn -s ${script.env.HOME}/jenkins.xml -o ${args}"
  }
}
上面的示例显示了传递到一个静态方法的脚本,该方法从脚本化管道调用,如下所示:

@Library('utils') import static org.foo.Utilities.*
node {
  mvn this, 'clean package'
}
在你的情况下,你应该写下如下内容:

def getLatestBuildDetails(context){
    //...
    executeCommand(context, 'git rev-parse HEAD')
    //...
}

def executeCommand(context, String command) {
    stdout = script.sh(script: command, returnStdout: true)
    return stdout.trim()
}
詹金斯档案:

@Library('library_name') _
getLatestBuildDetails(this)

有关更多信息,请参阅jenkins共享库文档:

您是否尝试直接对其进行硬编码并尝试
“git rev parse HEAD”。.execute().text
确保
.execute()
适合?啊@杰森·斯坦利,你确定你在做什么吗
sh
是的一个步骤,但是您发布的其他内容听起来不像您实际使用的Jenkins管道。你能添加更多细节吗?你在哪里使用给定的代码?@StephenKing我添加了更多的视角。
executeCommand
函数只有在我调用@NonCPS时才起作用,否则它就不起作用了。在传统的
Jenkinsfile
中,是的,这会起作用:)但是我使用的是Jenkins共享库,shell脚本是从库中调用的。哦,对不起,我误解了这个问题,请检查我的更新答案。我在尝试执行
curl
命令时遇到了与
Process
相同的问题。我需要摆脱它吗?