2009-12-16 13 views
7

Je me demande si quelqu'un connaît un moyen d'exécuter un programme conditionnel en fonction de la réussite de sortie/échec du programme précédent. Est-il possible pour moi d'exécuter un programme2 immédiatement après programme1 si programme1 se termine sans tester la variable LASTEXITCODE? J'ai essayé le -band et-et les opérateurs en vain, bien que j'ai eu le sentiment qu'ils ne fonctionneraient pas de toute façon, et le meilleur substitut est une combinaison d'un point-virgule et une déclaration if. Je veux dire, quand il s'agit de la construction d'un paquet un peu automatiquement de la source sous Linux, l'opérateur & & ne peut pas être battu:Exécuter processus conditionnellement dans Windows PowerShell (par exemple, le && et || opérateurs Bash)

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

PowerShell me demander de faire ce qui suit, en supposant que je pouvais utiliser le même construire le système dans PowerShell:

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

Bien sûr, je pourrais utiliser plusieurs lignes, enregistrez-le dans un fichier et exécuter le script, mais l'idée est qu'il soit concis (sauf les frappes). Peut-être que c'est juste une différence entre PowerShell et Bash (et même l'invite de commande Windows intégrée qui supporte l'opérateur & &) Je vais devoir m'adapter, mais s'il y a une manière plus propre de le faire, j'aimerais savoir .

+0

Quiconque s'intéresse au style Bash '&&' et '||' devient partie intégrante de PowerShell: veuillez voter pour la fonctionnalité [ici] (https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/11087898-implement-the-and-operators-that-bash-has). – mklement0

Répondre

2

Vous pouvez créer une fonction pour le faire, mais il n'y a pas une façon directe à ce que dois-je connais.

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 
} 

donnons le nom semblable à

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

Il y a probablement quelques erreurs là-bas cela est sans le brassard hors d'un environnement de pratique Powershell.

+0

Je vais l'ajuster au travail (Invoke-Expression est nécessaire car Invoke-Command ne fonctionne apparemment pas comme il le devrait ... ou quelque chose comme ça), mais c'est certainement utile. Merci pour l'aide. C'est grandement apprécié. – Dustin

+3

Le problème avec l'utilisation de '$ LASTEXITCODE' est qu'il ne se définit que lorsque PowerShell exécute une console EXE. Vous feriez peut-être mieux d'utiliser '$?'. –

+0

Vous pouvez ensuite alias cette fonction pour la rendre plus facile à invoquer. – GrayWizardx

0

je vraiment souffrais pour le manque de & &, aussi, donc écrit le script simple suivant basé sur la réponse de GrayWizardX (qui ne fonctionne pas comme-est):

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

Si vous enregistrez comme rc.ps1 (pour « run conditionnel ») dans un répertoire dans votre chemin, vous pouvez l'utiliser comme:

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

l'utilisation de blocs de script (les accolades) comme arguments au lieu de chaînes signifie que vous pouvez utiliser tout onglet d'achèvement taper les commandes, ce qui est muc h plus agréable. Ce script est presque aussi bon que & &, et fonctionne.

+1

Aussi, en changeant la quatrième ligne à 'if ($?) {Break; } 'fait que le script se comporte comme ||, au cas où cela ne serait pas évident. – Abram

+0

Ce n'est pas une bonne idée de _clear_ la collection '$ Error'; tester '$?' fera ('if ($?) {break}' pour '&&', et 'if (-not $?) {break}' pour '||'). Pour utiliser 'Invoke-Command', vous devez passer un _script block_, donc il est préférable de taper le paramètre' $ args' de cette façon: '[scriptblock []] $ args'. Aussi, pour éviter les effets secondaires, utilisez 'Invoke-Command -NoNewScope' - ou utilisez simplement l'opérateur' .' – mklement0