En todas las variantes de Unix tenemos tres flujos estándar que, a modo de canales, conectan la entrada y salida (I/O) de un comando/aplicación con la terminal/consola cuando se ejecuta, son los siguientes:
- standard input (stdin)
- standard output (stdout)
- standard error (stderr)
Vamos a explicar los usos que podemos dar estos tres canales para enviar y recoger los datos que surgen de la ejecución de un script, comando o aplicación.
standard input (stdin)
Stdin, o standard input son los datos que son enviados al programa, quizás cara al usuario de terminal sea el menos utilizado ya que lo normal suele ser interpretar los datos que el programa o comando envía, y no al revés. Normalmente stdin es texto enviado por el usuario, vamos a ver un ejemplo.
En un script en perl, podemos solicitar la interacción del usuario mediante STDIN, por ejemplo en este caso recogemos mediante STDIN el valor de dos variables que el usuario escribe:
#!/usr/bin/perl print "Introduce tu nombre:\n"; my $nombre = <STDIN>; print "Introduce tu apellido:\n"; my $apellido = <STDIN>;
Otro ejemplo que se me ocurre es el que puse en la entrada de automatizar comandos FTP, en este caso a la conexión FTP le pasamos de antemano los comandos a ejecutar:
ftp -inv direccion_ip<<FINFTP comando1 comando2 comando3 FINFTP
standard output (stdout)
A través de la salida estándar, «stdout» se reciben los datos que vuelca el comando o programa durante su ejecución, ejemplos sencillos de stdout serían por ejemplo el resultado de un «ls»,»cat» o cualquier otro comando de terminal. En cambio, hay otros comandos o programas que no muestran salida (a no ser que se especifique), como por ejemplo mover o copiar ficheros. Como ya sabemos cualquiera de estos flujos de datos se puede manipular, vamos a ver un ejemplo para comprender sus posibilidades.
Si hicieramos un «ls» a una carpeta, la salida de datos (stdout) se muestra en nuestra terminal:
$ ls backups cpq games local log opt spool www cache crash lib lock mail run tmp
Para manipular la salida estándar, utilizaremos el símbolo «>». Si por ejemplo quisieramos que stdout fuera redirigido a un fichero de texto, haríamos así:
$ ls > fichero.txt
Como podréis comprobar, por pantalla no aparece el resultado del comando, sino que se ha almacenado en el fichero indicado:
$ cat fichero.txt backups cpq games local log opt spool www cache crash lib lock mail run tmp
standard error (stderr)
A través del canal stderr los programas o comandos suelen enviar el informe de error de la ejecución de un comando en caso de fallar. En nuestros scripts o comandos podemos combinar el uso de stdout y stderr para separar la salida estándar de los errores, almacenarlos en registros independientes o manipularlos por separado.
En el siguiente ejemplo vamos a ejecutar un «ls» con parámetros incorrectos, por defecto la salida de errores se volcará en pantalla (terminal):
$ ls -7 ls: opción incorrecta -- '7' Pruebe `ls --help' para más información.
Si quisieramos almacenar los errores de la ejecución del comando en caso de suceder, podemos volcarlos usando en lugar del símbolo «>» el número 2 seguido de «>», «2>»:
$ ls -7 2> errores.log
Como podéis ver los errores ya no aparecen por pantalla, pero si abrimos el fichero de log tenemos el registro del fallo:
$ cat errores.log ls: opción incorrecta -- '7' Pruebe `ls --help' para más información.
Si quisieramos redirigir tanto el stdout como stderr al mismo sitio, en lugar de especificar dos veces el destino podemos hacerlo del siguiente modo «2>&1». Vamos a ver un ejemplo
Stdout y stderr a un fichero de log:
$ ls -3 > fichero.log 2>&1
Vamos a ver un ejemplo práctico de mysql. El comando mysqldump vuelca a stdout el dump de una base de datos, seguro que nos es más útil en un fichero que por pantalla, así mismo, si surge algún error nos conviene revisarlo así que lo volcamos a otro fichero distinto de log:
$ mysqldump test > test.sql 2> error.log
Otra opción es querer que tanto stdout como stderr vayan directamente a la basura (/dev/null):
$ ls -l > /dev/null 2>&1
Este es el uso más básico que podemos dar a estos tres importantes flujos estandar Unix, si tenéis cualquier duda podéis consultarla a través de los comentarios.
Hola Alejandro,
Estaba pensado hacer un artículo al respecto pero tú lo explicas tan bien, que lo voy a compartir ya mismo :)
Por cierto, genial blog!
¡Gracias David!
Excelente explicación. Saludos :)