2009-12-16 10 views
7

Mi chiedo se qualcuno conosca un modo per eseguire condizionatamente un programma a seconda dell'uscita riuscita/errore del programma precedente. Esiste un modo per eseguire un programma2 immediatamente dopo programma1 se il programma 1 termina correttamente senza testare la variabile LASTEXITCODE? Ho provato gli operatori a banda larga e senza successo, anche se avevo la sensazione che non avrebbero funzionato comunque, e il miglior sostituto è una combinazione di un punto e virgola e una dichiarazione if. Voglio dire, quando si tratta di costruire un pacchetto un po 'automaticamente dall'origine su Linux, l'operatore & & non può essere battuto:Esegui il processo in modo condizionale in Windows PowerShell (ad esempio gli operatori && e || in Bash)

# Configure a package, compile it and install it 
./configure && make && sudo make install 

PowerShell mi avrebbe bisogno di fare quanto segue, assumendo ho potuto effettivamente utilizzare lo stesso costruire il sistema in PowerShell:

# Configure a package, compile it and install it 
.\configure ; if ($LASTEXITCODE -eq 0) { make ; if ($LASTEXITCODE -eq 0) { sudo make install } } 

Certo, avrei potuto usare più righe, salvarlo in un file ed eseguire lo script, ma l'idea è per essere conciso (salvare combinazioni di tasti). Forse è solo una differenza tra PowerShell e Bash (e anche il prompt dei comandi integrato di Windows che supporta l'operatore & &). Avrò bisogno di adattarmi, ma se c'è un modo più pulito per farlo, mi piacerebbe sapere .

+0

Chiunque sia interessato a Bash-style '&&' e '||' diventa una parte di PowerShell: si prega di votare per la funzionalità [qui] (https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/11087898-attuazione-i-e-operatori-che-bash-ha). – mklement0

risposta

2

È possibile creare una funzione per farlo, ma non esiste un modo diretto per farlo che io conosca.

function run-conditionally($commands) { 
    $ranAll = $false 
    foreach($command in $commands) { 
     invoke-command $command 
     if ($LASTEXITCODE -ne 0) { 
      $ranAll = $false 
      break; 
     } 
     $ranAll = $true 
    } 

    Write-Host "Finished: $ranAll" 

    return $ranAll 
} 

Poi chiamano simile a

run-conditionally(@(".\configure","make","sudo make install")) 

Ci sono probabilmente alcuni errori là questo è a braccio, senza un ambiente PowerShell a portata di mano.

+0

Lo modifico per funzionare (Invoke-Expression è necessario perché Invoke-Command a quanto pare non funziona nel modo in cui dovrebbe ... o qualcosa del genere), ma è sicuramente qualcosa di utile. Grazie per l'aiuto. È molto apprezzato – Dustin

+3

Il problema con l'uso di '$ LASTEXITCODE' è che viene impostato solo quando PowerShell esegue un EXE di console. Potrebbe essere meglio usare '$?'. –

+0

È quindi possibile alias quella funzione per rendere più semplice il richiamo. – GrayWizardx

0

ero davvero facendo male per la mancanza di & &, anche, in modo scritto il seguente semplice script in base alla risposta del GrayWizardX (che non funziona così com'è):

foreach($command in $args) 
{ 
    $error.clear() 
    invoke-command $command 
    if ($error) { break; } 
} 

Se si salva come rc.ps1 (per "run condizionale") in una directory nel percorso, è possibile utilizzarlo come:

rc {.\configure} {make} {make install} 

Usando blocchi di script (le parentesi graffe) come argomenti, invece di stringhe significa che è possibile utilizzare il completamento scheda mentre digitando i comandi, che è muc più bello Questo script è quasi buono come & & e funziona.

+1

Inoltre, cambiando la quarta linea in 'if ($?) {Break; } 'fa sì che lo script si comporti come ||, nel caso in cui ciò non fosse ovvio. – Abram

+0

Non è una buona idea _clear_ la raccolta '$ Error'; testing '$?' farà ('if ($?) {break}' per '&&', e 'if (-not $?) {break}' per '||'). Per usare 'Invoke-Command', devi passare un _script block_, quindi è meglio digitare il parametro' $ args' in questo modo: '[scriptblock []] $ args'. Inoltre, per prevenire effetti collaterali, usa 'Invoke-Command -NoNewScope' - o semplicemente usa l'operatore' .'. – mklement0