2010-09-03 7 views
17

Necesito capturar la salida y el error de un comando en mi script bash y saber si el comando fue correcto o no.bash variable capture stderr y stdout por separado o obtenga el valor de salida

Por el momento, estoy capturando tanto como esto:

output=$(mycommand 2>&1) 

entonces necesito para comprobar el valor de salida de mycommand. Si falla, necesito hacer algunas cosas con la salida, si el comando tuvo éxito, no necesito tocar la salida.

Dado que estoy capturando la salida, ¿comprobando $? siempre es un 0 ya que bash logró capturar el resultado en la variable.

Este es un momento mismo de la escritura sensible, por lo que estamos tratando de evitar cualquier soluciones más lentas como la salida a un archivo y volver a leerlo en.

Si pudiera capturar la salida estándar de una variable y stderr a otro, eso resolvería mi problema porque podría simplemente verificar si la variable de error estaba vacía o no.

Gracias.

+4

Ver [BashFAQ/002] (http://mywiki.wooledge.org/BashFAQ/002) y [BashFAQ/047] (http://mywiki.wooledge.org/BashFAQ/047). –

Respuesta

8

¿Qué versión de bash estás usando? La captura de la salida tiene cero efecto sobre el código de retorno con mi versión, 4.1.5:

pax> false; echo $? 
1 
pax> echo $? 
0 
pax> x=$(false 2>&1) ; echo $? 
1 

No siempre es una buena idea confiar en ser no vacía para detectar errores de error estándar. Muchos programas no generan errores, pero confían en únicamente en el código de retorno.

+0

Olvidé mencionar que canalizo la salida de mi comando a otra. Aunque puedo hacer eso después de las salas en un comando separado. Gracias. – mhost

+3

¡Precaución! Tener 'local x = $ (falso 2> &1) ; echo $?' O 'set x = $ (falso 2> &1) ; echo $?' (Nota ** 'local/set' ** salidas' 0' no '1' como el último comando ejecutado es' local/set'. –

10

El problema sólo parece manifestarse cuando la salida es capturado a un variable local dentro de una función:

$ echo $BASH_VERSION 
3.2.48(1)-release 
$ false; echo $? 
1 
$ echo $? 
0 
$ x=$(false 2>&1) ; echo $? 
1 
$ function f { 
> local x=$(false 2>&1) ; echo $? 
> } 
$ f 
0 
$ function g { 
> x=$(false 2>&1) ; echo $? 
> } 
$ g 
1 

en cuenta que una única función f, que captura x a un local, puede expresar el comportamiento. Particularmente, funciona la función g que hace lo mismo, pero sin la palabra clave 'local'.

Por lo tanto, uno no puede usar una variable local, y tal vez 'desarmarla' después de su uso.

EDITAR NVRAM señala que la declaración local se puede hacer de antemano para evitar el problema:

$ function h { 
> local x 
> x=$(false 2>&1) ; echo $? 
> } 
$ h 
1 
+0

¡Muy interesante! Esto ocurre tanto en shell como en dash (posix) – Gregor

+3

En realidad $? Está configurado para la declaración de variable local, si simplemente lo declaras por en sí mismo, _then_ asígnelo en una línea separada, funcionará como usted desee. En otras palabras, agregue ** local x ** arriba de su línea con ** x = ** – NVRAM

Cuestiones relacionadas