简体   繁体   English

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

[英]Unable to run shell command in Groovy in Jenkins

I am trying to get certain values from the slave by running shell commands such as :我试图通过运行 shell 命令从从站获取某些值,例如:

git rev-parse HEAD
git config --get remote.origin.url

The method that I have tried to write for this is :我为此尝试编写的方法是:

def executeCommand(String command) {
    stdout = sh script: command, returnStdout: true
    return stdout.trim()
}

Now when I try to run the first command :现在,当我尝试运行第一个命令时:

output = executeCommand('git rev-parse HEAD')

I get the ERROR :我得到错误:

[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)

I also tried:我也试过:

output = command.execute().text

But this returns nothing.但这没有任何回报。

Im running out of ideas on how to run shell commands in Groovy in Jenkins and record the output.我没有关于如何在 Jenkins 中的 Groovy 中运行 shell 命令并记录输出的想法。

MORE DETAILS更多细节

I am working with Jenkins shared Libraries.我正在使用 Jenkins 共享库。 I have exposed a method in for my Jenkinsfile by the name getLatestBuildDetails() .我已经为我的Jenkinsfile公开了一个名为getLatestBuildDetails()的方法。 This method is defined within my library.这个方法是在我的库中定义的。 One of the actions within the method is to execute the git commands locally.该方法中的一项操作是在本地执行git命令。 So inorder to run any shell command locally, I have created the executeCommand function which takes the actual command to run as a String and executes it and returns the output to be used later by getLatestBuildDetails()因此,为了在本地运行任何 shell 命令,我创建了executeCommand函数,该函数将实际命令作为字符串运行并执行它并返回输出以供getLatestBuildDetails()稍后使用

Library classes cannot directly call steps such as sh or git . 库类不能直接调用sh或git等步骤 They can however implement methods, outside of the scope of an enclosing class, which in turn invoke Pipeline steps, for example: 但是,它们可以在封闭类的范围之外实现方法,而后者又调用Pipeline步骤,例如:

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

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

return this

Which can then be called from a Scripted Pipeline: 然后可以从脚本管道中调用它:

def z = new org.foo.Zot()
z.checkOutFrom(repo)

This approach has limitations; 这种方法有局限性; for example, it prevents the declaration of a superclass. 例如,它阻止了超类的声明。

Alternately, a set of steps can be passed explicitly using this to a library class, in a constructor, or just one method: 或者,可以使用此方法将一组步骤显式传递给库类,构造函数或只有一个方法:

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}"
  }
}

When saving state on classes, such as above, the class must implement the Serializable interface. 在类(例如上面)上保存状态时,该类必须实现Serializable接口。 This ensures that a Pipeline using the class, as seen in the example below, can properly suspend and resume in Jenkins. 这确保了使用该类的Pipeline(如下例所示)可以在Jenkins中正确挂起和恢复。

@Library('utils') import org.foo.Utilities
def utils = new Utilities(this)
node {
  utils.mvn 'clean package'
}

If the library needs to access global variables, such as env, those should be explicitly passed into the library classes, or methods, in a similar manner. 如果库需要访问全局变量(例如env),则应以类似的方式将这些变量显式传递到库类或方法中。

Instead of passing numerous variables from the Scripted Pipeline into a library, 而不是将多个变量从Scripted Pipeline传递到库中,

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}"
  }
}

The above example shows the script being passed in to one static method, invoked from a Scripted Pipeline as follows: 上面的示例显示了脚本被传递给一个静态方法,从Scripted Pipeline调用,如下所示:

@Library('utils') import static org.foo.Utilities.*
node {
  mvn this, 'clean package'
}

In your case you should write something like: 在你的情况下,你应该写如下:

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

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

Jenkins file: 詹金斯档案:

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

For more info see jenkins shared library documentation: https://jenkins.io/doc/book/pipeline/shared-libraries/ 有关更多信息,请参阅jenkins共享库文档: https ://jenkins.io/doc/book/pipeline/shared-libraries/

I am also using shared libraries.我也在使用共享库。 This is how I have used in my code:这就是我在代码中使用的方式:

String getMavenProjectName() {
    echo "inside getMavenProjectName +++++++"
    // mavenChartName = sh(
    //         script: "git config --get remote.origin.url",
    //         returnStdout: true
    // ).trim()
    def mavenChartName = sh returnStdout:true, script: '''
    #!/bin/bash
    GIT_LOG=$(env -i git config --get remote.origin.url)
    basename "$GIT_LOG" .git; '''
    echo "mavenChartName: ${mavenChartName}"
    return mavenChartName
}

Try out the sh step instead of execute. 尝试sh步而不是执行。 :) :)

EDIT: I would go with execute() or which I think it is even better, grgit . 编辑:我会使用execute()或者我认为它更好, grgit I think you are not getting any output when you run cmd.execute().text because .text returns the standard output of the command and your command might only use the standard error as its output, you can check both: 我认为你运行cmd.execute().text时没有得到任何输出,因为.text返回命令的标准输出,你的命令可能只使用标准错误作为输出,你可以检查两个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM