scripts script programas programacion operaciones manejo ejemplos comandos comando cadenas aritmeticas bash stderr io-redirection bash4

programas - ¿Qué método debo usar para escribir mensajes de error en ''stderr'' usando ''printf'' en un script de bash?



programacion shell linux ejemplos (4)

  1. Eso me parece razonable. Sin embargo, no necesita el 1 ; funcionará como está, pero está implícito:

    printf "{%s} This should go to stderr./n" "$(date)" >&2

  2. Tienes un problema de orden de operaciones:

    $ printf "{%s} Sent to stderr./n" "$(date)" 2> errors.txt 1>&2 $ ls -l errors.txt -rw-r--r-- 1 carl staff 47 Jun 9 11:51 errors.txt $ cat errors.txt {Sat Jun 9 11:51:48 PDT 2012} Sent to stderr.

Quiero dirigir la salida de un printf en un script de bash a stderr lugar de stdout .

No estoy preguntando acerca de la redirección de stderr o stdout desde donde se encuentren actualmente enrutados. Solo quiero poder enviar la salida de un printf a stderr lugar de al valor predeterminado de stdout .

Experimenté un poco y descubrí que agregar 1>&2 al printf , como se muestra en el siguiente ejemplo, parece hacer lo que quiero. Sin embargo, no tengo experiencia usando bash. ¿Entonces mi pregunta principal es si hay una forma " mejor " de hacer esto en bash ?

Por " mejor " me refiero a si hay otra forma de hacer esto que sea más comúnmente utilizada, más convencional o más idiomática. ¿Cómo lo haría un programador de bash más experimentado?

#!/bin/bash printf "{%s} This should go to stderr./n" "$(date)" 1>&2 printf "[(%s)] This should go to stdout./n" "$(date)"

También tengo una pregunta secundaria . Lo pregunto no tanto porque necesito saberlo, sino más bien porque tengo curiosidad y me gustaría entender mejor lo que está sucediendo.

Parece que lo anterior solo funcionará cuando se ejecuta dentro de un script de shell. No parece funcionar cuando lo intento desde una línea de comandos.

Aquí hay un ejemplo de lo que quiero decir.

irrational@VBx64:~$ printf "{%s} Sent to stderr./n" "$(date)" 1>&2 2> errors.txt {Sat Jun 9 14:08:46 EDT 2012} Sent to stderr. irrational@VBx64:~$ ls -l errors.txt -rw-rw-r-- 1 irrational irrational 0 Jun 9 14:39 errors.txt

Espero que el comando printf anterior no tenga salida porque la salida debería ir a stderr , que a su vez debería ir a un archivo. Pero esto no sucede. Eh


La pregunta parece indicar cierta confusión. No desea redireccionar stdout, solo desea que printf envíe su salida a stderr ... Pero para eso, debe usar la redirección.

El comando printf siempre envía la salida normal a su stdout. Eso es lo que hace printf. Para lograr lo que desea, debe tener la configuración de shell que stdout apunta temporalmente a donde desea que vaya la salida. Fíjate que digo temporalmente. Cuando escribes un comando como

$ printf "Hello World!" >&2

el shell modifica el controlador stdout durante la ejecución de la sentencia printf. Luego, el shell restaura el valor original de la salida estándar antes de continuar con el siguiente comando. De hecho, si desea redireccionar la salida estándar de forma permanente, use el comando especial

$ exec >&2

Después de que el shell haya ejecutado esto, el shell ya no recuerda el valor original del controlador stdout.


Los modismos típicos son:

echo foo >&2 # you don''t need to specify file descriptor 1 echo foo > /dev/stderr # more explicit, but wordier and less portable


Primero, sí, 1>&2 es lo correcto.

En segundo lugar, la razón por la que su ejemplo 1>&2 2>errors.txt no funciona es debido a los detalles de lo que hace exactamente la redirección.

1>&2 significa "hacer que el identificador de archivo 1 apunte a dondequiera que el identificador de archivo 2 actualmente", es decir, las cosas que se hubieran escrito en stdout ahora van a stderr. 2>errors.txt significa "abrir un errors.txt de errors.txt a errors.txt y hacer que el errors.txt de errors.txt 2 apunte a él", es decir, las cosas que se hubieran escrito en stderr ahora errors.txt en errors.txt . Pero el identificador de archivo 1 no se ve afectado en absoluto, por lo que las cosas escritas en stdout todavía van a stderr.

Lo correcto es 2>errors.txt 1>&2 , que hará que las escrituras tanto en stderr como en stdout vayan a errors.txt , porque la primera operación será "abrir errors.txt y hará que stderr apunte a él", y la segunda operación será "hacer que stdout apunte a donde stderr apunta ahora".