Posso far funzionare && in Powershell?


186

&&è notoriamente difficile da cercare su google, ma il migliore che ho trovato è questo articolo che dice di usare -and.

Sfortunatamente non fornisce ulteriori informazioni e non riesco a scoprire con cosa dovrei fare -and(di nuovo, una cosa notoriamente difficile da cercare)

Il contesto in cui sto cercando di usarlo è "esegui cmd1 e, in caso di successo, esegui cmd2", sostanzialmente questo:

csc /t:exe /out:a.exe SomeFile.cs && a.exe

Questo dovrebbe essere un semplice punto di riferimento per qualcuno che lo sa, grazie!


Modifica: se vuoi solo eseguire più comandi su una sola riga e non ti importa se il primo fallisce o no, puoi usare ;Per la maggior parte dei miei scopi questo va bene

Ad esempio: kill -n myapp; ./myapp.exe.


PowerShell ha operatori logici -e e -o. Gli operatori non funzionano nel modo previsto? In tal caso, puoi pubblicare l'espressione qui.
Mohit Chakraborty,

Vedere questa domanda, si fa ciò che si vuole: stackoverflow.com/questions/1917271/...
joshperry

2
Chiunque sia interessato allo stile Bash &&e ||diventi parte di PowerShell: vota qui per la funzione .
mklement0

1
Per quanto riguarda la necessità di eseguire ricerche Web per query con simboli letterali (e significativi): SymbolHound è utile per questo. Ecco alcuni esempi che riguardano la domanda: powershell && ; powershell -e . Se usi DuckDuckGo , puoi cercare SymbolHound tramite !sym.
nisavid,

3
Aggiornamento di giugno 2019 : il team di PowerShell sta implementando &&e ||! Pesa al GitHub PR
pilau

Risposte:


193

In CMD, '&&' significa "esegui il comando 1 e, se riesce, esegui il comando 2". L'ho usato per cose come:

build && run_tests

In PowerShell, la cosa più vicina che puoi fare è:

(build) -and (run_tests)

Ha la stessa logica, ma il testo di output dai comandi viene perso. Forse è abbastanza buono per te, però.

Se lo stai facendo in uno script, probabilmente starai meglio separando le dichiarazioni, in questo modo:

build
if ($?) {
    run_tests
}

27/11/2019 : l' &&operatore è ora disponibile per PowerShell 7 Preview 5+ :

PS > echo "Hello!" && echo "World!"
Hello!
World!

2
RE: "ridicolo che rimuoveranno" - Non mi piace pensare a PowerShell come "CMD con le parti stupide rimosse". is.gd/k92B
Jay Bazuzi,

91
Non mi piace pensare a PowerShell come "CMD con le parti stupide rimosse". Mi piace pensarlo come "Bash senza nessuna delle parti utili".
Pod

15
Puoi anche farlo build ; if ($?) { run_tests }dalla riga di comando.
docwhat,

19
Il modo più rapido per la vera frustrazione quando si apprende PowerShell è iniziare pensando che si tratti solo di un CMD espanso o di una bash. Ha un modello fondamentalmente diverso, soprattutto quando si tratta di input, output, piping e risultati. Inizia con un buon tutorial o una panoramica e non sforzarti troppo per far funzionare la sintassi di altre shell. Devi prenderlo alle sue condizioni.
Mark Meuer,

3
Prendendo PowerShell alle sue condizioni, come posso eseguire un comando e quindi, solo se quel comando ha esito positivo, eseguire un altro comando? Non penso che questo imponga bashidee su PowerShell. È la funzionalità di base della shell. Finora il migliore che ho visto è build ; if ($?) { run_tests }che userò d'ora in poi. Spero che il team di PowerShell aggiunga &&supporto!
Nate,

28

&& e || erano nell'elenco delle cose da implementare (lo sono ancora) ma non sono state visualizzate come la prossima cosa più utile da aggiungere. Il motivo è che abbiamo -AND e -OR. Se ritieni che sia importante, invia un suggerimento su Connect e lo prenderemo in considerazione per V3.


11
Mi sono registrato su Connect e mi sono nominato per PowerShell, ma non riesco a capire come inviare un suggerimento. Il sito Web Connect è davvero complesso e confuso :-(
Orion Edwards,

6
Non sono riuscito a trovare una richiesta preesistente, quindi ne ho fatta una: connect.microsoft.com/PowerShell/feedback/details/778798/…
Andy Arismendi

22
Sai, la domanda è ancora come scrivere un equivalente, e la tua risposta sarebbe molto più utile se aggiungessi un esempio di utilizzo -AND
Kyeotic

5
È importante perché è uno strumento di controllo del flusso di base utilizzato su sistemi più vecchi di Windows per quasi l'eternità. Quindi è presente ANCORA UN ALTRO differenza di rottura tra Linux e Windows.
airtonix,

6
Spero che Jeffrey Snover stia ascoltando, questo SO dovrebbe essere motivo sufficiente per implementarlo ormai. È passato troppo tempo e ora PowerShell inizia a comparire in alcuni punti, come VSCode lo utilizza come terminale predefinito in Windows. Questo è un dolore totale senza &&, -andmangia l'output, per niente equivalente.
Ciantic,

13

Prova questo:

$errorActionPreference='Stop'; csc /t:exe /out:a.exe SomeFile.cs; a.exe

9
Nota: se il primo comando fallisce, il secondo verrà comunque eseguito.
BrunoLM,

4
La variabile di preferenza $ErrorActionPreferenceregola solo il modo in cui vengono trattati gli errori non terminanti segnalati dai cmdlet ; utility esterne come csce a.exenon riportano mai tali errori (riflettono solo il loro stato di uscita in $?(flag di successo) e $LASTEXITCODE(il codice di uscita specifico riportato)), quindi la tua riga di comando equivale all'esecuzione incondizionata di entrambi i comandi (l'equivalente di cmd's csc /t:exe /out:a.exe SomeFile.cs & a.exe)
mklement0

5

Se il comando è disponibile in cmd.exe (qualcosa di simile python ./script.pyma non simile al comando PowerShell come ii .(Questo significa aprire la directory corrente da Explorer)), è possibile eseguire cmd.exe in PowerShell. La sintassi è così:

cmd /c "command1 && command2"

Qui, &&è fornito dalla sintassi cmd descritta in questa domanda .


4
Bene, esegui l'upgrade a cmd per accedere alla sua funzionalità aggiuntiva.
Bill K,

4

Ho provato questa sequenza di comandi in PowerShell:

Fisrt Test

PS C:\> $MyVar = "C:\MyTxt.txt"
PS C:\> ($MyVar -ne $null) -and (Get-Content $MyVar)
True

($MyVar -ne $null)restituito vero e (Get-Content $MyVar)anche restituito vero .

Secondo test

PS C:\> $MyVar = $null
PS C:\> ($MyVar -ne $null) -and (Get-Content $MyVar)
False

($MyVar -ne $null)restituito falso e finora devo assumere (Get-Content $MyVar)anche il falso restituito .

Il terzo test ha dimostrato che la seconda condizione non è stata nemmeno analizzata.

PS C:\> ($MyVar -ne $null) -and (Get-Content "C:\MyTxt.txt")
False

($MyVar -ne $null)restituito false e dimostrato che la seconda condizione (Get-Content "C:\MyTxt.txt")non è mai stata eseguita, restituendo false su tutto il comando.


Hai ragione! questo si comporta come l'operatore &&. Anche un $ () sul lato destro non permetterà di valutarlo!
Falco Alexander,

2

Domanda molto vecchia, ma per i nuovi arrivati: forse la versione di PowerShell (simile ma non equivalente ) che la domanda sta cercando, è quella di usare -andcome segue:

(build_command) -and (run_tests_command)


1
Questo potrebbe essere ok per il tuo caso d'uso, ma non si comporta come &&, in quanto ignora il codice di uscita di build_command.
Simon Buchan,

Questo sicuramente non sta facendo la cosa giusta. Eseguirà il secondo comando anche se il primo non è riuscito.
Nate,

questo è completamente sbagliato. ;è l'equivalente di &in cmd e ;in bash. Sicuramente non è lo stesso &&di cmd
phuclv,

Inoltre disattiva STDOUT e STDERR per entrambi i processi.
Dragas,

0

Dipende dal contesto, ma ecco un esempio di "-e" in azione:

get-childitem | where-object { $_.Name.StartsWith("f") -and $_.Length -gt 10kb }

Quindi sta diventando tutti i file più grandi di 10kb in una directory il cui nome inizia con "f".


1
Questa non è una risposta alla domanda originale, che riguarda l'esecuzione di più comandi.
bdukes il

0
if (start-process filename1.exe) {} else {start-process filename2.exe}

È un po 'più lungo di "&&" ma realizza la stessa cosa senza script e non è difficile da ricordare. Meglio tardi che mai. :)


2
Start-Processè lo strumento sbagliato da utilizzare per invocare le utilità della riga di comando in generale. In particolare, come utilizzato qui, Start-Processviene eseguito in filename1.exemodo asincrono in una nuova finestra della console e non restituisce nulla , che viene valutato in un contesto booleano $false. Anche se omettessi Start-Process(che è il modo in cui dovresti invocare le utility da riga di comando - direttamente), l'approccio non sarebbe all'altezza, perché il risultato del condizionale dipende dal fatto che l'utilità abbia prodotto un output stdout, che non ha alcuna relazione garantita con se riuscito o no.
mklement0

0

Penso che una semplice dichiarazione if possa realizzare questo. Quando ho visto la risposta di mkelement0 sopra che l'ultimo stato di uscita è memorizzato in $?, Ho messo insieme quanto segue:

# Set 1st command to variable
$a=somecommand

# Temp var to store exit status of last command (since we can't write to $?)
$test=$?

# Run Test
if ($test=$true) { 2nd-command }

Quindi, per l'esempio dell'operazione, sarebbe:

a=(csc /t:exe /out:a.exe SomeFile.cs); $test = $?; if ($test=$true) { a.exe }

0

Un equivalente dettagliato è combinare $LASTEXITCODEe -eq 0:

msbuild.exe args; if ($LASTEXITCODE -eq 0) { echo 'it built'; } else { echo 'it failed'; }

Non sono sicuro del perché if ($?)non abbia funzionato per me, ma questo ha funzionato.


-1

Possiamo provare questo comando invece di usare il metodo &&

prova {hostname; if ($ lastexitcode -eq 0) {ipconfig / all | findstr / i bios}} cattura {echo err} finalmente {}


Non v'è alcuna necessità di try/ catch, perché è necessaria solo per terminazione errori, che le utility esterne come hostname, ipconfige findstrnon può innescare. Il controllo $LASTEXITCODEè necessario solo se si desidera conoscere il codice di uscita specifico impostato da un'utilità esterna: il successo astratto o il fallimento si riflettono $?, proprio come con i cmdlet nativi.
mklement0

Penso che @Cyberiron sia sulla buona strada. Penso che &&in Unix sia molto simile a try / catch in quanto non richiede di avvolgere i comandi successivi in ​​un nuovo blocco (cioè }) quando si cortocircuita i comandi successivi (saltarli). Penso che una AmpAmpfunzione / filtro genera quando if (!?) { throw "last command failed" }sarebbe un sostituto molto utile per il porting &&su PowerShell. utilizzo :csc /t:exe /out:a.exe SomeFile.cs; AmpAmp; a.exe
yzorg
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.