2010-02-12 12 views
23

में वहां पहले से ही मेरी समस्या (Can I get && to work in Powershell?) को संबोधित करते हुए सवाल है, लेकिन एक अंतर के साथ है। मैं दोनों आदेशों से एक आउटपुट की जरूरत है। देखें, अगर मैं अभी चलाता हूं:सशर्त निष्पादन (&& और ||) powershell

(command1 -arg1 -arg2) -and (command2 -arg1) 

मुझे कोई आउटपुट नहीं दिखाई देगा, लेकिन stderr संदेश। और, जैसा कि अपेक्षित था, बस टाइपिंग:

command1 -arg1 -arg2 -and command2 -arg1 

वाक्यविन्यास त्रुटि देता है।

+0

क्या यह '-or' 'नहीं है? – stej

+1

एक लघु-परिसंचरण या केवल दूसरी अभिव्यक्ति निष्पादित करेगा यदि पहली बार गलत (विफल) के लिए evals। मुझे संदेह है कि ओपी दूसरी अभिव्यक्ति को केवल तभी निष्पादित करना चाहता है जब पहला सत्य (सफल) होता है जो एक शॉर्ट-सर्किटिंग-और हमें देता है। –

+0

जो कोई भी बैश-शैली '&&' और '||' में पावरशेल का हिस्सा बनने में रूचि रखता है: कृपया सुविधा के लिए वोट दें [यहां] (https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/11087898 -implement-और ऑपरेटरों-कि-बैश-है)। – mklement0

उत्तर

22

इस प्रयास करें:

$(command -arg1 -arg2 | Out-Host;$?) -and $(command2 -arg1 | Out-Host;$?) 

$() एक उपसूचक आप एक पाइप लाइन सहित भीतर कई बयानों निर्दिष्ट करने की अनुमति है। फिर आउट-होस्ट पर कमांड और पाइप निष्पादित करें ताकि आप इसे देख सकें। फिर अगली बयान उत्पादन $ (उपसूचक की वास्तविक उत्पादन) में? यानी अंतिम आदेश का सफलता परिणाम।

BTW $? देशी आदेश (सांत्वना exe के) के लिए ठीक काम करता है लेकिन cmdlets के लिए यह कुछ होना बाकी है। वह है, $? केवल $ झूठी वापस जाने के लिए जब एक cmdlet एक समाप्त त्रुटि का सामना करना पड़ता है। $ की तरह लगता है? कम से कम तीन राज्यों की आवश्यकता है (असफल, सफल और आंशिक रूप से सफल)। अभी भी

$(command -arg1 -arg2 -ev err | Out-Host;!$err) -and 
$(command -arg1 -ev err | Out-Host;!$err) 

चल रही इस तरह की: तो आप cmdlets का उपयोग कर रहे हैं, यह बेहतर काम करता है। शायद कुछ इस तरह बेहतर होगा:

function ExecuteUntilError([scriptblock[]]$Scriptblock) 
{ 
    foreach ($sb in $scriptblock) 
    { 
     $prevErr = $error[0] 
     . $sb 
     if ($error[0] -ne $prevErr) { break } 
    } 
} 

ExecuteUntilError {command -arg1 -arg2},{command2-arg1} 
+0

धन्यवाद, कीथ (बीटीडब्ल्यू, मैं पीएससीएक्स का उपयोग करता हूं और इसे बहुत अच्छा लगता हूं, उन लोगों के लिए बहुत धन्यवाद!)। हालांकि यह बहुत उपयोगी लगता है, यूनिक्स पाइपलाइन की तुलना में एक कमी है। निम्न पर विचार करें: 'command1 && command2 || command3'। यह बहुत आम पैटर्न है, मुझे लगता है। – Andy

+4

हाँ, यह उचित और& और || की तुलना में हैक का थोड़ा सा है समर्थन। –

+0

चूंकि (कम से कम) पीएसवी 2, _non-terminating_ त्रुटियां _do_ ''$?' '' False' सेट करें: उदाहरण के लिए, '$ null = Get-Item \, nosuch; $? 'आउटपुट' $ false'। _terminating_ त्रुटि के मामले में, कमांड लाइन/स्क्रिप्ट डिफ़ॉल्ट रूप से पूरी तरह से निरस्त हो जाएगी; यदि आप 'पकड़ने' की कोशिश करते हैं, तो 'पकड़' ब्लॉक में '$?' '$ false 'है, या यदि' पकड़ 'ब्लॉक खाली है, तुरंत बाद में; उदाहरण के लिए, 'कोशिश करें {फेंकने वाली त्रुटि "} पकड़ {}; $? ' – mklement0

2

जहां doThis multistep लिपियों आसान बनाने के लिए || बाहर निकलने के 1 वास्तव में उपयोगी हो सकता है, मैं की तरह कुछ का उपयोग करें:

function ProceedOrExit { 
    if ($?) { echo "Proceed.." } else { echo "Script FAILED! Exiting.."; exit 1 } 
} 

doThis; ProceedOrExit 
doNext 

# or for long doos 
doThis 
ProceedOrExit 
doNext 
0

थोड़ी देर तरीका है

कोशिश {होस्टनाम नीचे देखें; अगर ($ lastexitcode -eq 0) {ipconfig/all | findstr/मैं bios}} पकड़ {गूंज अं} अंत में {}

+0

'try'/'catch' की कोई आवश्यकता नहीं है, क्योंकि इसे केवल _terminating_ त्रुटियों के लिए जरूरी है, जो' होस्टनाम', 'ipconfig' और' findstr' जैसी बाहरी उपयोगिताओं को ट्रिगर नहीं कर सकता है। '$ LASTEXITCODE' की जांच केवल तभी जरूरी है जब आप बाह्य उपयोगिता द्वारा निर्धारित विशिष्ट निकास कोड जानना चाहते हैं - अमूर्त सफलता या विफलता 'cm?' में दिखाई देती है, जैसे मूल cmdlets के साथ। एक तरफ के रूप में: कृपया [अपने कोड को सही तरीके से प्रारूपित करें] (http://meta.stackexchange.com/a/22189/248777)। – mklement0

1
  • बैश के/cmd के && और || नियंत्रण ऑपरेटरों नहीं PowerShell समकक्ष, और जब से तुम PowerShell में कस्टम ऑपरेटरों को परिभाषित नहीं कर सकते हैं, वहाँ है कोई अच्छा काम नहीं है

    • Keith Hill's answer में | Out-Host आधारित वैकल्पिक हल एक गंभीर रूप से सीमित है कि यह केवल, सांत्वना (टर्मिनल) के लिए सामान्य आदेश उत्पादन भेज सकते हैं पाइप लाइन के माध्यम पर भेजा जा रहा है या एक में कब्जा किए जाने से उत्पादन को रोकने के चर या फ़ाइल। मेरा this answer में

ढूँढें पृष्ठभूमि जानकारी।

0

सरल समाधान एक cmd खोल में

powershell command1 && powershell command2 

उपयोग करने के लिए है। बेशक, आप इसे .ps1 स्क्रिप्ट में उपयोग नहीं कर सकते हैं, इसलिए उस सीमा है।