Groovy执行间歇性地没有输出或错误。

6
我将翻译以下it技术相关内容,涉及Groovy脚本和Git信息验证。

我正在尝试使用一个Groovy脚本(与jenkins-cli.jar一起运行)来验证一些Git信息。

为此,我有以下简单的Groovy脚本:

def getBranchSha = { branch ->
  def wd = new File('/my/git/repo');
  def sout = new StringBuffer(), serr = new StringBuffer();
  def gitcmd = 'git show-ref ' + branch + ' --hash';
  def proc = gitcmd.execute(null, wd);
  proc.consumeProcessOutput(sout, serr);
  proc.waitFor();

  def sha = sout.toString().trim();
  out.println("exitCode: " + proc.exitValue() + "\terror: " + serr.toString());
  out.println("input: " + branch + "\toutput: \"" + sha + "\"");
  assert sha.equals("10d94325c8fc1050f3e362d2fbb9f9041e6b9360");
}

getBranchSha("origin/master");

我希望这将构建一个命令行git show-ref origin/master --hash并在我的git repo的工作目录中执行。我预计输出的结果应该是当前SHA值,即此repo中的origin/master分支的SHA值10d94325c8fc1050f3e362d2fbb9f9041e6b9360,代码确认了这一点。
大多数情况下,此代码按预期运行,但有时出现空白输出的情况,我不知道原因。
 > while [ $? -eq 0 ] ; do java -jar jenkins-cli.jar -s http://localhost:8080 groovy tst.groovy ; done
exitCode: 0     error:
input: origin/master    output: "10d94325c8fc1050f3e362d2fbb9f9041e6b9360"
exitCode: 0     error:
input: origin/master    output: "10d94325c8fc1050f3e362d2fbb9f9041e6b9360"

...

exitCode: 0     error:
input: origin/master    output: "10d94325c8fc1050f3e362d2fbb9f9041e6b9360"
exitCode: 0     error:
input: origin/master    output: ""
java.lang.SecurityException: Rejected: org.codehaus.groovy.runtime.powerassert.PowerAssertionError
        at hudson.remoting.ClassFilter.check(ClassFilter.java:20)
        at hudson.remoting.MultiClassLoaderSerializer$Input.resolveClass(MultiClassLoaderSerializer.java:111)
        at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1612)
        at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
        at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
        at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
        at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
        at hudson.remoting.UserRequest.deserialize(UserRequest.java:184)
        at hudson.remoting.UserResponse.retrieve(UserRequest.java:217)
        at hudson.remoting.Channel.call(Channel.java:781)
        at hudson.remoting.RemoteInvocationHandler.invoke(RemoteInvocationHandler.java:250)
        at com.sun.proxy.$Proxy3.main(Unknown Source)
        at hudson.cli.CLI.execute(CLI.java:338)
        at hudson.cli.CLI._main(CLI.java:509)
        at hudson.cli.CLI.main(CLI.java:390)

根据零退出码,我认为该命令已经正常执行,但是我不明白为什么没有收到输出。我认为可能是因为我不知道 waitFor 应该如何工作,但是我已经尝试在函数的不同位置放置了 proc.waitFor() 行,但没有任何区别。

运行类似的脚本来验证 "pwd".execute().text.trim().equals("/") 看起来总是返回正确结果。

有什么想法吗?


如果您将new StringBuffer()更改为new StringWriter(),是否会遇到相同的问题? - tim_yates
我刚刚尝试了一下,它似乎做了同样的事情。 - laffoyb
如果您编写一个循环脚本,直接运行git show-ref origin/master --hash(而不运行脚本),是否有时会出现缺失输出? - tim_yates
不,我已经尝试过了,但在问题中没有提到。while [ $(git show-ref master --hash) == "10d94325c8fc1050f3e362d2fbb9f9041e6b9360" ] ; do sleep 1 ; echo "kay" ; done 看起来可以无限运行而没有任何问题。 - laffoyb
你可以尝试使用 def gitcmd = ['/bin/bash', '-c', "git show-ref $branch --hash"] 命令,查看是否是一个 shell 问题? - tim_yates
好主意,但结果完全一样。 - laffoyb
1个回答

5

我发现了一个可行的方法。与其将waitForconsumeProcessOutput一个接一个地调用(无论顺序如何),使用waitForProcessOutput方法可以可靠地将shell输出传递给我的groovy脚本。

def getBranchSha = { branch ->
  def wd = new File('/my/git/repo');
  def sout = new StringBuffer(), serr = new StringBuffer();
  def gitcmd = 'git show-ref ' + branch + ' --hash';
  def proc = gitcmd.execute(null, wd);
  proc.waitForProcessOutput(sout, serr);

  def sha = sout.toString().trim();
  out.println("exitCode: " + proc.exitValue() + "\terror: " + serr.toString());
  out.println("input: " + branch + "\toutput: \"" + sha + "\"");
  assert sha.equals("10d94325c8fc1050f3e362d2fbb9f9041e6b9360");
}

getBranchSha("origin/master");

这段代码将会给我想要的结果。但是我不明白为什么使用waitForconsumeProcessOutput的组合不能达到同样的效果。

这在 Groovy 2.5.2 版本中对我有效。我正在使用 mp3info 命令处理 500 多个 mp3 文件,有时候使用 consumeProcessOutput(sout, serr) / waitFor() 没有输出。改为使用 waitForProcessOutput(sout, serr) 后,每次都能正常工作。 - A.W.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接