¿Hay alguna manera de redirigir SOLO stderr a stdout (no combinar los dos) para que pueda ser canalizado a otros progtwigs?

Estoy trabajando en un entorno Windows CMD.EXE y me gustaría cambiar el resultado de stdout para que coincida con el de stderr para poder canalizar los mensajes de error a otros progtwigs sin la intermediación de un archivo.

Soy consciente de la notación 2>&1 , pero eso combina stdout y stderr en una sola transmisión.

Lo que estoy pensando sería algo como esto:

 program.exe 2>&1 | find " " 

Pero eso combina stdout y stderr al igual que:

 program.exe | find " " 2>&1 

Me doy cuenta de que podría hacer …

 program 2>file type file | find " " del file 

Pero esto no tiene la flexibilidad y el poder de un program | find " " program | find " " tipo de notación. Hacer esto requiere que el program haya terminado con su salida antes de que esa salida pueda procesarse.

Interesante pregunta 🙂

CMD procesa la redirección de izquierda a derecha. Primero quiere redirigir 2 (stderr) a & 1 (stdout), luego redirigir 1 (stdout) a otra cosa. En este punto, stderr seguirá siendo redirigido a la definición previa de stdout. La tubería seguirá funcionando con la antigua definición de stdout (que ahora contiene stderr).

Si no le importa la salida estándar, puede redireccionar a nul

 program.exe 2>&1 1>nul | find " " 

Si desea capturar stdout en un archivo, redirija a un archivo

 program.exe 2>&1 1>yourFile | find " " 

Si aún desea ver stdout en la consola, pero solo quiere conectar stderr a FIND, puede redirigir 1 a con:

 program.exe 2>&1 1>con: | find " " 

Tenga en cuenta que existe una diferencia sutil entre la definición original de stdout y con: Por ejemplo, cls >con: no borra la pantalla, sino que imprime un personaje divertido en la pantalla.

Es posible cambiar realmente stdout y stderr si usa un tercer manejador de archivo (inicialmente no utilizado). 1 y 3 contendrán la definición original de stderr, y 2 contendrán la definición original de stdout.

 program.exe 3>&2 2>&1 1>&3 | find " " 

En realidad, hay un identificador de archivo adicional definido cada vez que se realiza una redirección. La definición original se guarda en el primer identificador de archivo no utilizado disponible. Supongamos que no ha habido ninguna redirección antes de emitir el comando anterior. 3>&2 no guardan la definición original de 3 porque 3 no se definió previamente. Pero 2>&1 guardan la definición original de stderr en 4 (3 ya se han utilizado), y 1>&2 guardan la definición original de stdout en 5.

Así que, técnicamente, la redirección explícita de 3 no es necesaria para intercambiar stderr y stdout

 program.exe 2>&1 1>&3 | find " " 

2>&1 guarda stderr en 3 y 2 se redirige a & 1 (stdout). 1>&3 guardan la salida estándar en 4 y 1 se redirigen a & 3 (stderr).

Pero lo anterior solo funcionará correctamente si está seguro de que 3 aún no se ha definido antes de emitir el comando. Es mucho más seguro definir explícitamente 3 como en mi ejemplo de código anterior.

Ver ¿Por qué mi stderr redirection no termina después de que termine el comando? ¿Y cómo lo arreglo? para algunas aventuras realmente salvajes con redirección 🙂

Si mira http://support.microsoft.com/kb/110930 , parece que desea 2>&1 1>NUL . Entonces algo como lo siguiente debería funcionar para usted:

 test.exe 2>&1 1>NUL | find "someErrorString"