سؤال

رائع يضيف execute طريقة String لجعل تنفيذ قذائف إلى حد ما سهلة ؛

println "ls".execute().text

ولكن إذا كان خطأ يحدث, ثم لا يوجد أي الناتج. هل هناك طريقة سهلة للحصول على كل معيار الخطأ القياسي ؟ (من إنشاء مجموعة من التعليمات البرمجية ؛ إنشاء اثنين من المواضيع قراءة كل inputstreams ، ثم استخدام أحد الوالدين تيار الانتظار بالنسبة لهم لإكمال ثم تحويل سلاسل العودة إلى النص؟)

سيكون من الجميل أن يكون لديك شيء من هذا القبيل ؛

 def x = shellDo("ls /tmp/NoFile")
 println "out: ${x.out} err:${x.err}"
هل كانت مفيدة؟

المحلول

حسنا حلها نفسي ؛

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

يعرض:

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

نصائح أخرى

"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()
// 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()
}

إضافة واحد أكثر أهمية المعلومات أعلاه قدمت إجابات -

عملية

def proc = command.execute();

دائما حاول استخدام

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

بدلا من

def output = proc.in.text;

إلى النواتج بعد تنفيذ الأوامر في رائع وهذا الأخير هو حجب المكالمات (حتى السؤال عن السبب).

أجد هذا أكثر الاصطلاحية:

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"

آخر مشاركة يذكر أن هذه هي حجب المكالمات, ولكن بما أننا نريد أن نعمل مع الإخراج ، قد يكون هذا ضروريا.

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]
command = "ls *"

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

ولكن إذا كان الأمر فشل عملية إنهاء

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top