2011-08-17 8 views
8

¿hay alguna manera fácil en PowerShell de enviar una cadena a variable y consola al mismo tiempo?cómo dar salida a una cadena a variable y consola al mismo tiempo

quiero capturar el resultado de mi script en una variable para poder analizarlo al final del script, guardarlo en un archivo de registro y también enviar un correo electrónico a un operador.

mi intención es tener una salida de $ variable y añadir cualquier cadena de salida a la misma y también de salida a la consola de inmediato algo así como

$output="Process started" 

$output=+"Doing step 1" 
"Doing step 1" 

$output=+"Doing step 2" 
"Doing step 2" 

así que al final me puedo ahorrar $ salida a un archivo de registro, correo electrónico y analizarlo.

Jugué con tee-object que podría funcionar para ese propósito, pero desafortunadamente reescribía mi variable de salida $ en lugar de anexarle una cadena.

ACTUALIZACIÓN Esta es la solución final que decidí seguir, gracias a manojlds!

$script:output = "" 

filter mylog { 
    $script:output+= $_+"`n" 
    return $_ 
} 


"doing step {0}" -f 1 | mylog 
"doing step {0}" -f 2 | mylog 
"doing step {0}" -f 3 | mylog 

#in the end of the script 
$script:output 

Respuesta

5

Hay tantas maneras de conseguir su objetivo final:

En su script simplemente tener algo como esto:

"Process started" 
<step1> 
"Doing step 1" 
<step2> 
"Doing step 2" 
... 

A continuación, ejecute la secuencia de comandos como

.\test.ps1 | Tee-Object -file log.txt 

Tenga en cuenta que la salida está disponible e a Tee-Object y, por lo tanto, a la consola cuando ocurra. No obtiene el resultado solo después de que se ejecuta todo el script. Así es como funciona la tubería en Powershell. Los objetos se pasan aguas abajo a medida que ocurren. Inserte un sleep 10 entre medio como pasos y verifique que la salida llegue tan pronto como esté disponible.

Además, no necesariamente tiene que tener otra secuencia de comandos (the launcher.ps1) de la que está hablando. Puede usar funciones, scriptblock, etc. dentro de su script.

Algunas otras maneras:

function test { 

"Process started" 
sleep 5 
"Doing step 1" 
sleep 5 
"Doing step 2" 

} 

test | %{$output+=$_;$_} 
#use output 
write-host -fore blue $output 

puede crear un filtro:

$script:output = "" 

filter appendOutput { 

    $script:output+= $_ 
    return $_ 
} 

"Process started" | appendOutput 
sleep 5 
"Doing step 1" | appendOutput 
sleep 5 
"Doing step 2" | appendOutput 
#use output 
write-host -fore blue $script:output 

Probablemente hay muchas más formas de hacer esto.

+0

así es como lo implementé primero, pero terminé con dos scripts. Ahora tengo un script más complejo y necesito hacer un análisis en el script de llamada, lo que hace que mi script de llamada sea complejo. Acabo de encontrar esta publicación http://get-powershell.com/post/2008/06/26/Stuffing-the-output-of-the-last-command-into-an-automatic-variable.aspx y estoy pensando ahora si puedo hacer algo así anulando-predeterminado – mishkin

+0

lo siento solo para dejarme en claro ... Tengo mi script principal (digamos main.ps) y launcher.ps (algo así como tu. \ test.ps1 | Tee- Object -file log.txt) para que el iniciador capture el resultado del script principal. Si bien funciona, tengo dos problemas con este enfoque: no veo nada en la consola hasta que mi script principal haya finalizado y no pueda hacer ningún análisis/análisis en mi script principal – mishkin

+0

@mishking - '. \ Test.ps1 | Tee-Object -file log.txt' - si está haciendo eso, verá el resultado en la consola cuando ocurra. Agregue un 'sleep 10' entre las cadenas en el script anterior y vea. También vea mi respuesta actualizada – manojlds

-1
("Process started" | out-host) | Set-Variable x ; $x 
+0

gracias pero no funciona - $ x se reiniciará cada vez que lo necesito para acumular toda la salida de script – mishkin

+0

-1. ¡Esto ni siquiera funciona! '$ x' estaría vacío, porque' out-host' ya tiene la cadena, obtendrá una salida de eso para set-variable, que no es nada (escribir en el host no significa que esté disponible en la tubería). – manojlds

1

No me he equivocado con PowerShell lo suficiente como para dar una respuesta concreta, pero si tuviera que hacer esto en C, explotaría los efectos secundarios.

//Psuedo-C 
string con (oldString, newString) { 
    print(newString); 
    return oldString + newString; 
} 

Utilice la función de este modo:

myString = con(myString, "Process started"); 

Se tendría el efecto deseado. (dejando de lado la sintaxis correcta de C y la pedantería, como tratar con líneas nuevas) no sé cómo traducir esto a Powershell.

Lo que quiere hacer puede considerarse desordenado sin embargo.Podría ser más claro si solo expira y registra explícitamente la salida y registra uno después del otro en su código. Los efectos secundarios inevitablemente vuelven a morderte. Mantenga las cosas modulares.

5

Este es un buen truco, encierre su asignación de variable entre paréntesis. Puede encontrar más información sobre esto en la especificación del lenguaje PowerShell (sección 7.1.1 Agrupamiento paréntesis) disponible para descargar here:

PS > ($var=1) 
1 
PS > 
+0

¡increíble! es un truco muy bueno y gracias por las especificaciones de buena información que hay. Este truco no ayudará mucho en mi caso porque si necesito acumular salida en una sola var algo como: $ output = "" ($ output + = "haciendo el paso {0}" -f 1) ($ salida + = "haciendo paso {0}" -f 2) y obtendrá: realizar el paso 1 realizar el paso 1doing paso 2 que se pegaba con un filtro de momento como manojlds sugirió anteriormente. – mishkin

1

que estaba viendo algo similar a esto, con la excepción de que no necesitaba para analizarla luego, solo recolecta la salida.

Algo que otra persona podría ver ya que parece que tiene su respuesta está utilizando transcripciones de PowerShell (Start-Transcript y Stop-Transcript). Encontré en este site que tiene algunos problemas cuando aparece un error del servidor, pero él muestra cómo lo manejó.

+0

gracias! podría funcionar para algunas personas y también investigué eso, pero tiene limitaciones como la que se describe aquí http://blogs.msdn.com/b/powershell/archive/2010/01/04/workaround-for-start- transcript-on-native-processes.aspx – mishkin

Cuestiones relacionadas