2 votes

Ecrire dans la sortie standard à l'intérieur des rappels et des fonctions

Je suis nouveau dans powershell et il semble que j'ai du mal avec son concept de "pipes". Comme je le comprends :

  • Write-Host écrit sur "la console" mais ne peut pas être réutilisé/ capturé par d'autres scripts
  • Write-Output met quelque chose dans la pipe. Si le contenu de la pipe n'est pas utilisé ailleurs, il est affiché sur la console. Un script appelant peut utiliser la sortie.

Dans la plupart des langages de script que je connais, vous pouvez écrire sur la console de n'importe où de manière à ce qu'elle puisse être utilisée par d'autres scripts appelants sans affecter la valeur de retour d'une fonction.

Alors :

  • Quel est l'avantage de ceci? Pour le moment, cela semble élégant par conception mais pas vraiment pratique.
  • Comment puis-je écrire la sortie du script à partir d'une fonction sans affecter sa valeur de retour (non, je ne peux pas utiliser [Write-Host][1])
  • Comment puis-je écrire la sortie du script à partir d'un callback/événement comme dans

    $ect = Register-ObjectEvent -InputObject $ps -Action { Write-Somewhere $EventArgs.Data } -EventName 'ErrorDataReceived' 

Contexte : le script est appelé à partir d'un fichier wrapper, qui est lui-même appelé à partir d'un fichier wrapper appelé depuis Jenkins. Write-Output est correctement enregistré mais je ne peux pas l'utiliser partout. Je veux éviter de mettre du texte dans un fichier temporaire et le relire à la fin pour conserver le timing.

1voto

Ben N Points 38070

Un effet utile de la distinction entre Write-Host et Write-Output est que vous pouvez insérer des logs (Write-Host) dans vos fonctions sans perturber les valeurs qu'elles retournent effectivement à leurs appelants (Write-Output).

En parlant de retour aux appelants, laisser simplement une valeur sortir d'une expression ou de l'invocation d'une commande la transmettra en sortie. Par conséquent, 5 sur une ligne à lui seul et Write-Output 5 sont équivalents. Un concept quelque peu délicat est que les scripts PowerShell n'ont pas de valeurs de retour au sens propre comme la plupart des langages de programmation. Retourner une valeur avec le mot clé Return est indiscernable du fait de laisser la valeur sortir de la pipeline de sortie puis de quitter la fonction. En d'autres termes, 5; break est la même chose que Return 5. La sortie du script (qui peut être plusieurs objets) est la valeur de retour.

Les objets sortant des blocs de script enregistrés en tant qu'actions d'événement sont automatiquement stockés dans la propriété Output de l'objet job de l'événement, c'est ce que vous obtenez en retour de Register-ObjectEvent si vous utilisez -Action pour fournir un bloc de script. Voici un exemple de script qui enregistre la date et l'heure actuelles à chaque fois qu'un minuteur se déclenche :

$timer = New-Object System.Timers.Timer
$timer.Interval = 2000
$myEvent = Register-ObjectEvent $timer -EventName 'Elapsed' -Action {Get-Date}
$timer.Start()

La variable $myEvent recevra l'objet job de Register-ObjectEvent. $myEvent.Output sera un tableau en constante augmentation des horaires, un à chaque exécution de Get-Date dans le gestionnaire d'événements. (Il y a quelques variables automatiquement définies qui peuvent être utiles dans de tels gestionnaires.) Dans votre cas, une fois que tout ce qui génère les rappels est terminé, vous pourriez sortir $ect.Output pour transmettre les données capturées au script appelant.

Alternativement, si vous ne voulez pas gérer des gestionnaires d'événements personnalisés, vous pouvez omettre le bloc de script et plutôt fournir un identifiant de source qui nomme l'abonnement à l'événement. Nous pourrions remplacer la ligne $myEvent de l'exemple précédent par ceci :

Register-ObjectEvent $timer -EventName 'Elapsed' -SourceIdentifier 'MyEvent'

Maintenant les événements vont dans la file d'attente des événements, marqués avec notre identifiant de source. Pour les récupérer plus tard, nous utilisons Get-Event :

Get-Event -SourceIdentifier 'MyEvent'

0voto

Alan Points 41

En premier lieu, si vous voulez des détails sur le fonctionnement de Write-Output (et sur la façon dont il est censé fonctionner), consultez la réponse de BenN.

Ni Write-Output ni Write-Host ne fonctionnent vraiment pour moi. Mais Powershell offre plus d'options pour écrire à l'écran et pour offrir des canaux de sortie. J'ai choisi d'utiliser Write-Verbose. Je n'ai pas le contrôle sur le script appelant mais heureusement, le canal Verbose est déjà fusionné avec la sortie standard.

Si ce n'est pas le cas, vous devez fusionner la sortie de débogage avec la sortie standard manuellement:

.\test_writing_to_debug_output.ps1 4>&1 > a_logfile.txt

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X