शेल आदेशों को निष्पादित करने वाला ग्रूवी


178

ग्रूवी निष्पादन के गोले को काफी आसान बनाने के लिए executeविधि जोड़ता Stringहै;

println "ls".execute().text

लेकिन अगर कोई त्रुटि होती है, तो कोई परिणामी आउटपुट नहीं है। क्या मानक त्रुटि और मानक दोनों को बाहर निकालने का एक आसान तरीका है? (कोड का एक गुच्छा बनाने के अलावा, दोनों इनपुट्स पढ़ने के लिए दो धागे बनाएँ; फिर एक मूल धारा का उपयोग करके उन्हें पूरा करने के लिए प्रतीक्षा करें फिर स्ट्रिंग को पाठ में परिवर्तित करें?)

ऐसा कुछ होना अच्छा होगा;

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

यह लिंक उपयोगी है। दिखाता है कि CURL डेमो के साथ शेल कमांड कैसे चलाना है।
अनिकेत ठाकुर

जवाबों:


207

ठीक है, इसे खुद हल किया;

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


13
यदि आपको इस प्रक्रिया में पर्यावरण चर सेट करने की आवश्यकता है , तो शेल में कमांड को लपेटना सुनिश्चित करें। उदाहरण के लिए, env vars के साथ एक Perforce कमांड चलाना:envVars = ["P4PORT=p4server:2222", "P4USER=user", "P4PASSWD=pass", "P4CLIENT=p4workspace"]; workDir = new File("path"); cmd = "bash -c \"p4 change -o 1234\""; proc = cmd.execute(envVars, workDir);
Noam Manos

@paul_sns ओपी प्रश्न से असंबंधित है, लेकिन मुझे लगता है कि आधुनिक जेवीएम अनियंत्रित सिंक्रनाइज़ेशन को ठीक से संभालते हैं। इसलिए StringBuffer थ्रेड या स्टैक-सीमित परिदृश्य में प्रदर्शन को नीचा दिखाने की संभावना नहीं है।
पावेल ग्रुशेत्स्की

3
डॉक्स का कहना है कि हमें waForProcessOutput () का उपयोग करना चाहिए - "आउटपुट के लिए प्रतीक्षा करने के लिए पूरी तरह से कॉल waForProcessOutput () का उपभोग करने के लिए"। स्रोत: docs.groovy-lang.org/latest/html/groovy-jdk/java/lang/…
श्रीकांत

4
@srikanth WaitForProcess () आउटपुट डॉक्स भी कहता है "इस विधि का उपयोग करें यदि आप मानक या त्रुटि आउटपुट के बारे में परवाह नहीं करते हैं और बस प्रक्रिया को चुपचाप चलाना चाहते हैं" - मैं आउटपुट चाहता हूं
Bob Herrmann

वेटफॉरऑर्क के बाद भी sout और serr उपलब्ध नहीं हो सकता है। प्रिटंल के बजाय एस्टर का उपयोग करके परीक्षण किया गया। डॉक्स कहते हैं: "इसके लिए, दो थ्रेड्स शुरू किए जाते हैं, इसलिए यह विधि तुरंत वापस आ जाएगी। थ्रेड्स शामिल नहीं होंगे () एड, भले ही वेटफ़ोर () कहा जाता है । आउटपुट के पूरी तरह से प्रतीक्षा करने के लिए प्रतीक्षा करने के लिए कॉल फ़ॉरफ़ॉरसेंटस ऑउटपुट () । । "
solstice333

49

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

यह बॉर्न अगेन शेल स्क्रिप्ट के साथ काम नहीं कर रहा है! # / Bin / bash,
रश्मि जैन

1
यदि आप बैश स्क्रिप्ट के साथ काम कर रहे हैं, तो आप संभवतः कमांड के भाग के रूप में बैश को आमंत्रित करते हैं: "/ बिन / बैश स्क्रिप्ट" .execute ()
Niels Bech Nielsen

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

10
+1 यह आउटपुट को सृजनात्मक रूप से दिखाता है क्योंकि आउटपुट उत्पन्न होता
है..जो

वहाँ महान शेयर @ mholm815
जिमी ओबोनियो अबोर

2
इस समाधान का उपयोग करने के लिए, निम्नलिखित लाइन जारी करें:runCommand("echo HELLO WORLD")
Miron V

@ mholm815 हम पाइपलाइन से आवश्यक स्क्रिप्ट को कैसे अनुमोदित कर सकते हैं?
रौनक पटेल

25

मुझे यह अधिक मुहावरेदार लगता है:

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"

जैसा कि एक अन्य पोस्ट में कहा गया है, ये कॉल को रोक रहे हैं, लेकिन चूंकि हम आउटपुट के साथ काम करना चाहते हैं, इसलिए यह आवश्यक हो सकता है।


24

ऊपर दिए गए उत्तरों में एक और महत्वपूर्ण जानकारी जोड़ने के लिए -

एक प्रक्रिया के लिए

def proc = command.execute();

हमेशा उपयोग करने का प्रयास करें

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

बजाय

def output = proc.in.text;

ग्रूवी में आदेशों को निष्पादित करने के बाद आउटपुट को कैप्चर करने के लिए क्योंकि उत्तरार्द्ध एक अवरुद्ध कॉल ( कारण के लिए एसओ प्रश्न ) है।


6
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]

3
मुझे वास्तव में गुस्सा आ रहा है कि एक व्यक्ति ने जवाब देने के लिए समय लिया और किसी ने बिना किसी स्पष्ट कारण के इसे नीचे गिरा दिया। यदि यह एक समुदाय है, तो किसी को टिप्पणी जोड़ने के लिए बाध्य होना चाहिए (जब तक कि यह बहुत स्पष्ट कारण नहीं है कि कोई भी सक्षम प्रोग्रामर तुरंत देख लेगा)।
अमोस बॉरदविज

6
@AmosBordowitz जवाब के बहुत सारे नीचे उतरते हैं। यह ठीक है, यह एक डाउनवोट है। यह कहा, यह हो सकता है क्योंकि यह स्पष्टीकरण के बिना शब्द के साथ कोड है - हमेशा अच्छी तरह से प्राप्त नहीं।
क्रिस बेकर

@ क्रिसबकेर क्यों इसे इंगित नहीं किया गया? आप स्वयं सकारात्मक नहीं हैं कि यही कारण है ..
अमोस बोर्डोविट

5
@AmosBordowitz मैं आधिकारिक डाउनवॉटर व्याख्याता नहीं हूं, मैं आपको नहीं बता सकता कि क्यों नहीं, और यह समझ में आता है कि मैं निश्चित नहीं हूं क्योंकि हम किसी अन्य व्यक्ति द्वारा की गई कार्रवाई के बारे में बात कर रहे हैं। मैंने एक संभावना पेश की। क्यों नहीं समझा नीचे, यकीन है, क्यों जवाब में कोड की व्याख्या नहीं? किसी भी दर पर, मुझे यकीन है कि हम सब ठीक हो जाएंगे।
क्रिस बेकर

1
@ChrisBakerI ने कभी ऐसा कोई दावा नहीं किया ("लेकिन मुझे लगता है कि आप बेहतर जानते हैं")। यह एक शालीनता की बात है, ज्ञान की बात नहीं ..
अमोस बोर्डोविट

-3
command = "ls *"

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

लेकिन अगर आदेश विफल हो जाता है तो प्रक्रिया समाप्त हो जाएगी


कहाँ shसे आता है?
style3r

3
shजेनकींस groovy DSL का हिस्सा है। शायद यहाँ उपयोगी नहीं है
Gi0rgi0s

4
जेनकिंस ग्रूवी डीएसएल! = ग्रूवी
स्कीवे

जैसा कि दूसरों ने कहा है, यह जेनकींस डीएसएल का एक हिस्सा है
jonypony3

यह उत्तर उस प्रश्न पर लागू नहीं है जो पूछा गया था।
ब्रैंडन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.