web-dev-qa-db-fra.com

le code de sortie de la commande n'est pas le même que le code de sortie d'un script

J'ai besoin d'exécuter un script avec PowerShell -Commande "& scriptname", et j'aimerais vraiment que le code de sortie que je récupère de PowerShell soit le même que le code de sortie que le script lui-même a renvoyé. Malheureusement, PowerShell renvoie 0 si le script renvoie 0 et 1 si le script renvoie une valeur non nulle comme illustré ci-dessous:

PS C:\test> cat foo.ps1
exit 42
PS C:\test> ./foo.ps1
PS C:\test> echo $lastexitcode
42
PS C:\test> powershell -Command "exit 42"
PS C:\test> echo $lastexitcode
42
PS C:\test> powershell -Command "& ./foo.ps1"
PS C:\test> echo $lastexitcode
1
PS C:\test>

Utiliser [Environnement] :: Exit (42) fonctionne presque:

PS C:\test> cat .\baz.ps1
[Environment]::Exit(42)
PS C:\test> powershell -Command "& ./baz.ps1"
PS C:\test> echo $lastexitcode
42
PS C:\test>

Sauf que lorsque le script est exécuté de manière interactive, il quitte l'intégralité du shell. Aucune suggestion?

27
ediven

Si vous regardez la pièce que vous envoyez à -Command en tant que script, vous verrez que cela ne fonctionnera jamais. Le script exécutant le foo.ps1 le script n'a pas d'appel à quitter, il ne renvoie donc pas de code de sortie.

Si vous retournez un code de sortie, il fera ce que vous voulez. Modifiez-le également de " à ', autrement $lastexitcode sera résolu avant d'envoyer la chaîne au deuxième PowerShell, si vous l'exécutez à partir de PowerShell.

PS C:\test> powershell -Command './foo.ps1; exit $LASTEXITCODE'
PS C:\test> echo $lastexitcode
42

PS: consultez également le -File paramètre si vous souhaitez simplement exécuter un script. Mais sachez aussi que ce n'est pas return 1 si vous avez une erreur de terminaison comme -Command Est-ce que. Voir ici pour en savoir plus sur ce dernier sujet.

PS C:\test> powershell -File './foo.ps1'
PS C:\test> echo $lastexitcode
42
31
Lars Truijens

CAVEAT: si votre script PowerShell renvoie des codes de sortie SUPÉRIEURS À 65535, ils sont remplacés:

$exitCode = 65536
Exit $exitCode

Si le CMD suivant appelle ce script PS1 ci-dessus, vous obtiendrez un% errorlevel% de

Powershell.exe "& 'MyPowershellScript.ps1' "; exit $LASTEXITCODE
SET ERR=%ERRORLEVEL%

et un code de sortie de 65537 vous donnerait un% errorlevel% de 1, etc.

Pendant ce temps, si un CMD en appelle un autre et que le script enfant renvoie un niveau d'erreur supérieur à 65535, il passe très bien.

Cmd /c exit 86666

Le CMD renverra un% errorlevel% de 86666 comme prévu.

CAVEAT à tout cela: maintenant cela se produit en marche et en arrêt sans raison apparente.

4
Mr. Annoyed

Comment appelez-vous votre script de manière interactive?

J'ai essayé cela et cela semble fonctionner correctement, mais je l'appelle à partir de l'invite DOS, pas dans PowerShell

C:\Temp>type foo.ps1
exit 42


C:\Temp>powershell -noprofile -nologo -noninteractive -executionpolicy Bypass -file .\foo.ps1

C:\Temp>echo %errorlevel%
42

c:\Temp>
1
ProfessionalAmateur