Comment puis-je écrire à l'erreur standard dans PowerShell?
j'ai du mal à comprendre comment faire écho au flux d'erreur standard et rediriger le flux d'erreur d'un exécutable.
je viens d'un Bourne shell et Korn shell arrière-plan, dont je voudrais utiliser;
# Write to stderr
echo "Error Message!" >&2
# Redirect stderr to file
/do/error 2>/tmp/err.msg
3 réponses
Utiliser Write-Error
pour écrire à stderr. Pour rediriger stderr à l'utilisation du fichier:
Write-Error "oops" 2> /temp/err.msg
ou
exe_that_writes_to_stderr.exe bogus_arg 2> /temp/err.msg
notez que PowerShell écrit les erreurs comme des enregistrements d'erreurs. Si vous voulez éviter la sortie détaillée des enregistrements d'erreur, vous pouvez écrire l'erreur info vous-même comme ceci:
PS> Write-Error "oops" -ev ev 2>$null
PS> $ev[0].exception
oops
-EV
est court (un pseudonyme) pour -ErrorVariable
. Toute erreur sera stockée dans la variable nommée par l'argument de ce paramètre. PowerShell signalera quand même l'erreur à la console, sauf si nous rediriger l'erreur $null
.
ce que vous voulez probablement est ceci:
$host.ui.WriteErrorLine('I work in any PowerShell host')
vous pouvez aussi voir ce qui suit, mais il suppose que votre hôte PS est une console fenêtre/de l'appareil, donc je considère qu'il est moins utile:
[Console]::Error.WriteLine('I will not work in the PowerShell ISE GUI')
Remarque:
Cette réponse est sur le écrire à stderr du point de vue de la monde extérieur quand un script PowerShell est appelé de là; alors que la réponse est écrite du point de vue de Windows shell,
cmd.exe
, il s'applique également à Unix coques, telles quebash
lorsqu'il est combiné avec le noyau PowerShell.par contraste,à partir de à l'intérieur de Powershell, vous devez utiliser
Write-Error
, comme expliqué dans la réponse de Keith Hill.malheureusement, il y a aucun unifié approche à partir de à l'intérieur de PowerShell et à partir de l'extérieur - voir cette réponse de moi pour une discussion.
ajouter @Chris Sear est génial répondre à:
$host.ui.WriteErrorLine
devrait fonctionner dans tous les hôtes, il n'a pas (par défaut) d'écrire sur la sortie stderr lorsqu'il est appelé par cmd.exe
, comme à partir d'un fichier de commandes.
[Console]::Error.WriteLine
par contre, toujours.
si vous voulez écrire un script PS qui joue bien en termes de flux de sortie lorsqu'il est invoqué à partir de cmd.exe
, utilisez la fonction suivante, Write-StdErr
, qui utilise [Console]::Error.WriteLine
dans l'ordinaire de PS / cmd.exe
hôte (fenêtre de la console) et $host.ui.WriteErrorLine
sinon:
<#
.SYNOPSIS
Writes text to stderr when running in a regular console window,
to the host''s error stream otherwise.
.DESCRIPTION
Writing to true stderr allows you to write a well-behaved CLI
as a PS script that can be invoked from a batch file, for instance.
Note that PS by default sends ALL its streams to *stdout* when invoked from
cmd.exe.
This function acts similarly to Write-Host in that it simply calls
.ToString() on its input; to get the default output format, invoke
it via a pipeline and precede with Out-String.
#>
function Write-StdErr {
param ([PSObject] $InputObject)
$outFunc = if ($Host.Name -eq 'ConsoleHost') {
[Console]::Error.WriteLine
} else {
$host.ui.WriteErrorLine
}
if ($InputObject) {
[void] $outFunc.Invoke($InputObject.ToString())
} else {
[string[]] $lines = @()
$Input | % { $lines += $_.ToString() }
[void] $outFunc.Invoke($lines -join "`r`n")
}
}
Informations générales facultatives:
interne, PS a plus que les flux de sortie traditionnels (stdout et stderr), et leur nombre a augmenté avec le temps (essayez Write-Warning "I'll go unheard." 3> $null
comme exemple, et en lire plus à Get-Help about_Redirection
; a noter que la page n'a pas encore compte de flux 6
Write-Information
, introduit dans PSv5).
lors de l'interfaçage avec le monde extérieur, PS doit carte les flux de sortie non traditionnels vers stdout et stderr.
Étrangement, cependant, PowerShell par défaut envoie ses flux (y compris Write-Host
et $host.ui.WriteErrorLine()
sortie) stdout lorsqu'elle est invoquée à partir de cmd.exe
, même si mapper le flux d'erreurs de PowerShell à stderr serait le choix logique. Ce comportement est en vigueur depuis (au moins) v2 et s'applique toujours à partir de v5.1 (et ne changera probablement pas pour des raisons de rétrocompatibilité).
Vous pouvez le vérifier avec la commande suivante si vous l'invoquez de cmd.exe
:
powershell -noprofile -command "'out'; Write-Error 'err'; Write-Warning 'warn'; Write-Verbose -Verbose 'verbose'; $DebugPreference='Continue'; write-debug 'debug'; $InformationPreference='Continue'; Write-Information 'info'; Write-Host 'host'; $host.ui.WriteErrorLine('uierr'); [Console]::Error.WriteLine('cerr')" >NUL
la commande écrit à tous les flux de sortie PS (lorsque vous exécutez sur une version pré-PSv5, vous verrez un message d'erreur supplémentaire relatif à Write-Information
, qui a été introduit dans PSv5) et a cmd.exe
redirection stdout seulementNUL
(i.e.,supprimer sortie stdout; >NUL
).
Vous allez voir aucun sortie à l'exception de cerr
([Console]::Error.WriteLine()
, qui écrit directement à stderr) - tous les flux de PowerShell ont été envoyés à stdout.
peut-être encore plus étrangement, il permet de capturer des PowerShell du flux d'erreur, mais seulement avec une redirection:
si vous changez >NUL
2>NUL
ci-dessus, il est exclusivement PowerShell flux d'erreur et $host.ui.WriteErrorLine()
sortie qui sera supprimée; bien sûr, comme avec n'importe quel de redirection, vous pouvez l'envoyer à un le fichier.
(Comme l'a dit, [Console]::Error.WriteLine()]
toujours sorties vers stderr, que cette dernière soit redirigée ou non.)
pour donner un exemple plus précis (encore une fois, exécutez cmd.exe
):
powershell -noprofile -command "'out'; Write-Error 'err'" 2>NUL
Le dessus de sorties out
-Write-Error
's la sortie est réprimer.
Pour résumer:
Sans (
cmd.exe
) redirection ou avec stdout redirection (>...
ou1>...
), PowerShell envoie ses flux de sortie vers stdout.Avec un stderr redirection (
2>...
), PowerShell sélectivement envoie ses flux d'erreur pour stderr (que stdout soit redirigé ou non).comme corollaire, l'idiome commun suivant Fait fonctionne comme prévu:
powershell ... >data-output.txt
Comme on pouvait s'y attendre, cela n'enverra pas seulement stdout dans le fichierdata-output.txt
lors de l'impression d' stderr sortie vers le terminal; au lieu de cela, vous devez utilisezpowershell ... >data-output.txt 2>err-output.tmp; type err-output.tmp >&2; del err-output.tmp
Il s'ensuit que PS est conscient de cmd.exe
les redirections et ajuste son comportement intentionnellement.
(Ceci est également évident à partir de PS produisant couleur sortie cmd.exe
console lors de la suppression des codes de couleur lorsque la sortie est redirigée vers un fichier.)
si je manque quelque chose et/ou quelqu'un peut fournir une justification de conception pour ce comportement, s'il vous plaît laissez-nous savoir.