2010-02-12 11 views
23

Istnieje już pytanie dotyczące mojego problemu (Can I get && to work in Powershell?), ale z jedną różnicą. Potrzebuję OUTPUT z obu poleceń. Zobacz, jeśli po prostu uruchomię:wykonywanie warunkowe (&& i ||) w trybie uprawnień

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

Nie zobaczę żadnych komunikatów wyjściowych, ale stderr. I, zgodnie z oczekiwaniami, wystarczy wpisać:

command1 -arg1 -arg2 -and command2 -arg1 

Podaje błąd składni.

+0

Czy to nie "-or"? – stej

+1

Krótkofalówka LUB wykona drugie wyrażenie tylko wtedy, gdy pierwsza jest fałszywa (błąd). Podejrzewam, że OP chce, aby drugie wyrażenie zostało wykonane tylko wtedy, gdy pierwsze zeskoczyło na prawdę (sukces), co spowodowało zwarcie - i dało nam. –

+0

Ktokolwiek jest zainteresowany stylem Bash '&&' i '||' staje się częścią PowerShell: zagłosuj na funkcję [tutaj] (https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/11087898 -implement-and-operator-that-bash-has). – mklement0

Odpowiedz

22

Spróbuj tego:

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

dolarów() jest podwyrażenie pozwala określić wiele deklaracje wewnątrz tym rurociągu. Następnie wykonaj polecenie i potokuj do Out-Host, abyś mógł je zobaczyć. Następnie w następnej instrukcji (rzeczywiste wyjście podwyrażenia) wyprowadzamy $? tj. wynik sukcesu ostatniej komendy.

BTW the $? działa dobrze dla natywnych poleceń (exe konsoli), ale dla cmdletów pozostawia wiele do życzenia. To znaczy, $? tylko wydaje się zwracać $ false, gdy polecenie cmdlet napotyka błąd zakończenia. Wydaje się, że $? potrzebuje co najmniej trzech państw (nie udało się, udało się i częściowo udało). Więc jeśli używasz poleceń cmdlet, działa to lepiej:

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

Ten rodzaj ciosów wciąż. Być może coś takiego byłoby lepiej:

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

Dzięki, Keith (BTW, używam PSCX i znajduję to świetnie, wielkie dzięki za te!). Choć wydaje się to całkiem użyteczne, jest to wada w porównaniu do potoku UNIX. Rozważ następujące: 'command1 && command2 || command3'. Myślę, że to dość powszechny wzór. – Andy

+4

Tak, to trochę hack w porównaniu do właściwego && i || wsparcie. –

+0

Od (co najmniej) PSv2, _non-terminating_ errors _do_ ustaw '$?' Na '$ false': na przykład' $ null = Get-Item \, nosuch; $? 'output' $ false'. W przypadku błędu _terminating_, linia poleceń/skrypt domyślnie przerwałby całkowicie; jeśli spróbujesz 'try' /' catch' błędu, '$?' to '$ false' w bloku' catch' lub, jeśli blok 'catch' jest pusty, natychmiast potem; np. "try {throw" kończący err "} catch {}; $? ' – mklement0

2

Aby uprościć skrypty wieloetapowych, gdzie doThis || exit 1 byłoby bardzo przydatne, używam coś takiego:

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

doThis; ProceedOrExit 
doNext 

# or for long doos 
doThis 
ProceedOrExit 
doNext 
0

trochę dłużej sposobem jest zobaczyć poniżej

try {hostname; if ($ lastexitcode -eq 0) {ipconfig/all | findstr/i bios}} catch {echo err} finally {}

+0

Nie ma potrzeby używania 'try' /' catch', ponieważ jest to potrzebne tylko w przypadku błędów _terminating_, których zewnętrzne narzędzia, takie jak 'nazwa hosta',' ipconfig' i 'findstr' nie mogą wywołać. Sprawdzanie '$ LASTEXITCODE' jest potrzebne tylko, jeśli chcesz poznać kod wyjścia określony przez zewnętrzne narzędzie - streszczenie sukcesu lub porażki jest odzwierciedlone w' $? ', Podobnie jak w natywnych cmdletach. Na marginesie: proszę [odpowiednio sformatuj swój kod] (http://meta.stackexchange.com/a/22189/248777). – mklement0

1
  • /cmd „s && i || operatorzy kontroli Bash mają NO PowerShell ekwiwalenty, a ponieważ nie można zdefiniować operatorów niestandardowe w PowerShell, tam są brak dobrych obejść.

    • | Out-Host -na obejście w Keith Hill's answer jest silnie ograniczony, może on wysyłać tylko normalne wyjście polecenia do konsoli (terminal), uniemożliwiając wyjście przed wysłany przez rurę lub są zrobione w zmienna lub plik.

znaleźć informacje w tle this answer kopalni.

0

Najprostszym rozwiązaniem jest użycie

powershell command1 && powershell command2 

w cmd powłoki. Oczywiście nie można tego użyć w skrypcie .ps1, więc istnieje takie ograniczenie.