Groovy执行shell命令

lxkprmvk  于 2023-03-17  发布在  Shell
关注(0)|答案(7)|浏览(249)

Groovy在String中添加了execute方法,使shell的执行变得相当容易;

println "ls".execute().text
    • 有没有一种简单的方法可以同时获得标准错误和标准输出?**(除了创建一堆代码来创建两个线程来读取两个输入流,使用父流等待它们完成,然后将字符串转换回文本之外?)

如果有这样的东西就好了;

def x = shellDo("ls /tmp/NoFile")
 println "out: ${x.out} err:${x.err}"
swvgeqrz

swvgeqrz1#

好吧,我自己解决了;

def sout = new StringBuilder(), serr = new StringBuilder()
def proc = 'ls /badDir'.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println "out> $sout\nerr> $serr"

显示器:
out> err> ls: cannot access /badDir: No such file or directory

imzjd6km

imzjd6km2#

"ls".execute()返回一个Process对象,这就是"ls".execute().text工作的原因。您应该能够读取错误流以确定是否存在任何错误。
Process上有一个额外的方法,允许您传递一个StringBuffer来检索文本:consumeProcessErrorStream(StringBuffer error) .
示例:

def proc = "ls".execute()
def b = new StringBuffer()
proc.consumeProcessErrorStream(b)

println proc.text
println b.toString()
biswetbf

biswetbf3#

// a wrapper closure around executing a string                                  
// can take either a string or a list of strings (for arguments with spaces)    
// prints all output, complains and halts on error                              
def runCommand = { strList ->
  assert ( strList instanceof String ||
           ( strList instanceof List && strList.each{ it instanceof String } ) \
)
  def proc = strList.execute()
  proc.in.eachLine { line -> println line }
  proc.out.close()
  proc.waitFor()

  print "[INFO] ( "
  if(strList instanceof List) {
    strList.each { print "${it} " }
  } else {
    print strList
  }
  println " )"

  if (proc.exitValue()) {
    println "gave the following error: "
    println "[ERROR] ${proc.getErrorStream()}"
  }
  assert !proc.exitValue()
}
wpx232ag

wpx232ag4#

我觉得这句话更地道:

def proc = "ls foo.txt doesnotexist.txt".execute()
assert proc.in.text == "foo.txt\n"
assert proc.err.text == "ls: doesnotexist.txt: No such file or directory\n"

正如另一篇文章提到的,这些都是阻塞调用,但由于我们希望处理输出,这可能是必要的。

chhkpiq4

chhkpiq45#

在前面的答案中再添加一条重要信息:
对于一个过程

def proc = command.execute();

总是尝试使用

def outputStream = new StringBuffer();
proc.waitForProcessOutput(outputStream, System.err)
//proc.waitForProcessOutput(System.out, System.err)

而不是

def output = proc.in.text;

捕获在Groovy中执行命令后的输出,因为后者是一个阻塞调用(SO question for reason)。

wkyowqbh

wkyowqbh6#

def exec = { encoding, execPath, execStr, execCommands ->

    def outputCatcher = new ByteArrayOutputStream()
    def errorCatcher = new ByteArrayOutputStream()

    def proc = execStr.execute(null, new File(execPath))
    def inputCatcher = proc.outputStream

    execCommands.each { cm ->
        inputCatcher.write(cm.getBytes(encoding))
        inputCatcher.flush()
    }

    proc.consumeProcessOutput(outputCatcher, errorCatcher)
    proc.waitFor()

    return [new String(outputCatcher.toByteArray(), encoding), new String(errorCatcher.toByteArray(), encoding)]
}

def out = exec("cp866", "C:\\Test", "cmd", ["cd..\n", "dir\n", "exit\n"])

println "OUT:\n" + out[0]
println "ERR:\n" + out[1]
ikfrs5lh

ikfrs5lh7#

command = "ls *"

def execute_state=sh(returnStdout: true, script: command)

但如果命令失败,则过程将终止。

相关问题