Write-To-StdOut dentro de callbacks e funções

1

Sou novo no powershell e parece que tenho problemas com o conceito de tubos. Pelo que entendi:

  • Write-Host escreve "no console", mas não pode ser reutilizado / capturado de outros scripts
  • Write-Output coloca algo no tubo. Se o conteúdo do pipe não for usado em outro lugar, ele será despejado no console. Um script de chamada pode usar a saída.

Em virtualmente todas as linguagens de script, sei que você pode escrever no console de qualquer lugar, de uma maneira que possa ser usado a partir de scripts de chamada e sem afetar o valor de retorno de uma função.

Então:

  • Qual é o benefício disso? No momento, parece elegante por design, mas não é realmente prático.
  • Como posso escrever na saída do script de dentro de uma função sem afetar seu valor de retorno (não, não posso usar [Write-Host][1] )
  • Como posso escrever na saída do script a partir de um retorno de chamada / evento como

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

Background: o script é chamado a partir de um arquivo wrapper, chamado a partir de um arquivo wrapper chamado de Jenkins. Write-Output está logado corretamente, mas eu não posso usá-lo em todos os lugares. Eu quero evitar despejo de texto em um arquivo temporário e lê-lo de volta no final para conservar o tempo.

    
por Peter Schneider 27.10.2017 / 15:52

2 respostas

0

Primeiramente, se você quiser detalhes sobre como o Write-Output funciona (e se pretende funcionar), veja a resposta do BenN.

Nem o Write-Output nem o Write-Host estão realmente funcionando para mim. Mas o Powershell tem mais opções para escrever na tela e produzir canais para oferecer. Optei por usar Write-Verbose . Eu não estou no controle do roteiro de chamada, mas, felizmente, o canal Verbose já está mesclado com a saída padrão.

Se não for esse o caso, você precisará mesclar a saída de depuração na saída padrão manualmente:

.\test_writing_to_debug_output.ps1 4>&1 > a_logfile.txt
    
por 01.11.2017 / 15:00
1

Um efeito útil da distinção entre Write-Host e Write-Output é que você pode inserir o log ( Write-Host ) em suas funções sem atrapalhar os valores que eles realmente retornam para seus chamadores ( Write-Output ).

Por falar em retornar aos chamadores, simplesmente deixar um valor sair de uma expressão ou chamada de cmdlet o transmitirá como saída. Portanto, 5 em uma linha por si só e Write-Output 5 são equivalentes. Um conceito um tanto complicado é que os scripts do PowerShell não têm valores de retorno no mesmo sentido que a maioria das linguagens de programação. Retornar um valor com a palavra-chave Return é indistinguível de permitir o valor do pipeline de saída e, em seguida, sair da função. Em outras palavras, 5; break é o mesmo que Return 5 . A saída do script (que pode ser vários objetos) é o valor de retorno.

Objetos que saem de blocos de script registrados como ações de evento são automaticamente escondidos na propriedade Output do objeto de trabalho do evento, que é o que você recebe de Register-ObjectEvent se você usar -Action para fornecer um bloco de script . Aqui está um script de exemplo que registra a data e a hora atuais toda vez que um timer é disparado:

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

A variável $myEvent receberá o objeto de trabalho de Register-ObjectEvent . $myEvent.Output será uma matriz cada vez maior de vezes, uma de cada execução de Get-Date no manipulador de eventos. (Há alguns definidos automaticamente variáveis que podem ser úteis em tais manipuladores.) No seu caso, uma vez terminado o que for feito gerando os retornos de chamada, você poderá gerar $ect.Output para passar os dados capturados para o script de chamada.

Como alternativa, se você não deseja lidar com manipuladores de eventos personalizados, pode deixar o bloco de script e, em vez disso, fornecer um identificador de origem que nomeie a assinatura do evento. Poderíamos substituir a linha $myEvent do exemplo anterior por:

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

Agora, os eventos entram na fila de eventos, marcados com nosso identificador de origem. Para recuperá-los mais tarde, usamos Get-Event :

Get-Event -SourceIdentifier 'MyEvent'
    
por 27.10.2017 / 22:38

Tags