2012-06-19 21 views
30

में exec() आउटपुट का उपयोग कैसे करें मैं पर्यावरण परिवर्तनीय मानों और खोल निष्पादन की श्रृंखला से गतिशील रूप से buildsignature.properties फ़ाइल बनाने के लिए एक क्रमिक कार्य को कार्यान्वित करने का प्रयास कर रहा हूं। मेरे पास यह ज्यादातर काम कर रहा है, लेकिन मुझे खोल कमांड का आउटपुट नहीं मिल रहा है। यहां मेरा कार्य है ...ग्रेडल

task generateBuildSignature << { 
    ext.whoami = exec() { 
     executable = "whoami" 
    } 
    ext.hostname = exec() { 
     executable = "hostname" 
    } 
    ext.buildTag = System.env.BUILD_TAG ?: "dev" 

    ant.propertyfile(
     file: "${buildDir}/buildsignature.properties", 
     comment: "This file is automatically generated - DO NOT EDIT!") { 
     entry(key: "version", value: "${project.version}") 
     entry(key: "buildTimestamp", value: "${new Date().format('yyyy-MM-dd HH:mm:ss z')}") 
     entry(key: "buildUser", value: "${ext.whoami}") 
     entry(key: "buildSystem", value: "${ext.hostname}") 
     entry(key: "buildTag", value: "$ext.buildTag") 
    } 
} 

लेकिन परिणामस्वरूप गुण फ़ील्ड buildUser और buildSystem के वांछित परिणाम नहीं प्राप्त करता है।

#This file is automatically generated - DO NOT EDIT! 
#Mon, 18 Jun 2012 18:14:14 -0700 
version=1.1.0 
buildTimestamp=2012-06-18 18\:14\:14 PDT 
buildUs[email protected]2e6a54f9 
buildSyst[email protected]46f0bf3d 
buildTag=dev 

मैं कैसे buildUser और buildSystem इसी कार्यकारी बजाय कुछ डिफ़ॉल्ट ExecResultImpl toString के उत्पादन में मैच के लिए मिलता है? यह वास्तव में कठिन नहीं हो सकता है, है ना?

उत्तर

28

यह post वर्णन करता है कि आउटपुट को Exec आमंत्रण से कैसे पार्स करें। नीचे आपको दो कार्य मिलेंगे जो आपके आदेश चलाते हैं।

task setWhoamiProperty { 
    doLast { 
     new ByteArrayOutputStream().withStream { os -> 
      def result = exec { 
       executable = 'whoami' 
       standardOutput = os 
      } 
      ext.whoami = os.toString() 
     } 
    } 
} 

task setHostnameProperty { 
    doLast { 
     new ByteArrayOutputStream().withStream { os -> 
      def result = exec { 
       executable = 'hostname' 
       standardOutput = os 
      } 
      ext.hostname = os.toString() 
     } 
    } 
} 

task printBuildInfo { 
    dependsOn setWhoamiProperty, setHostnameProperty 
    doLast { 
     println whoami 
     println hostname 
    } 
} 

शैल कमांड का आह्वान किए बिना इस जानकारी को प्राप्त करने का वास्तव में एक आसान तरीका है।

वर्तमान में उपयोगकर्ता के प्रवेश: System.getProperty('user.name')

होस्ट का नाम: InetAddress.getLocalHost().getHostName()

+0

आसान बेहतर है। मैं वास्तव में एक शेल कमांड के आउटपुट को कैप्चर करने की उम्मीद नहीं करता था, आउटपुट स्ट्रीम को पार्स करने के लिए हाथ की आवश्यकता होती है। कोई बात नहीं। मार्गदर्शन के लिए धन्यवाद। –

+3

त्वरित प्रश्न, क्या आपका कोड 'standardOutput = os' गायब नहीं है ?? –

+0

जब हम ऐसा करते हैं तो यह असीमित लगता है। यह मौजूद होने से पहले व्हामी और मेजबाननाम को आउटपुट करने का प्रयास करता है। विचार? –

50

यह वह जगह है कार्यकारी से stdout प्राप्त करने के लिए मेरी पसंदीदा वाक्य रचना:

def stdout = new ByteArrayOutputStream() 
exec{ 
    commandLine "whoami" 
    standardOutput = stdout; 
} 
println "Output:\n$stdout"; 

यहाँ मिला: http://gradle.1045684.n5.nabble.com/external-process-execution-td1431883.html (ध्यान दें कि पृष्ठ है हालांकि एक टाइपो और ByteArrayOutputStream के बजाय ByteArrayInputStream का उल्लेख करता है)

+0

ग्रेडल 3.3: यह काम नहीं कर रहा है। अगर मैं println पर टिप्पणी करता हूं तो कुछ नहीं होता है, अगर मैं इसे असम्बद्ध करता हूं - आउटपुट में कई नई लाइनें हैं, तो यह अजीब है लेकिन यहां तक ​​कि "आउटपुट" शब्द भी नहीं है – Tertium

2

Gradle docs for Exec से पैराफ्रेशेड:

task execSomething { 
    exec { 
    workingDir '/some/dir' 
    commandLine '/some/command', 'arg' 

    ... 
    //store the output instead of printing to the console: 
    standardOutput = new ByteArrayOutputStream() 

    //extension method execSomething.output() can be used to obtain the output: 
    ext.output = { 
     return standardOutput.toString() 
    } 
    } 
} 
संबंधित मुद्दे