Si está familiarizado con los comandos básicos de Linux, también debería aprender el concepto de redirección de entrada y salida.
Ya sabes cómo funciona un comando de Linux. Toma una entrada y te da una salida. Hay algunos jugadores en la escena aquí. Déjame hablarte de ellos.
Stdin, stdout y stderr
Cuando ejecuta un comando de Linux, hay tres flujos de datos que juegan un papel en él:
- La entrada estándar (stdin) es la fuente de los datos de entrada. De manera predeterminada, stdin es cualquier texto ingresado desde el teclado. Su ID de transmisión es 0.
- La salida estándar (stdout) es el resultado del comando. Por defecto, se muestra en la pantalla. Su ID de transmisión es 1.
- Error estándar (stderr) es el mensaje de error (si lo hay) producido por los comandos. De forma predeterminada, stderr también se muestra en la pantalla. Su ID de transmisión es 2.
Estos flujos contienen los datos en texto sin formato en lo que se denomina memoria intermedia.
Piense en ello como una corriente de agua. Necesitas una fuente de agua, un grifo por ejemplo. Le conectas una tubería y puedes guardarlo en un balde (archivo) o regar las plantas (imprimirlo). También puede conectarlo a otro grifo, si es necesario. Básicamente, estás redirigiendo el agua.
Linux también tiene este concepto de redirección, donde puede redirigir stdin, stdout y stderr desde su destino habitual a otro archivo o comando (o incluso dispositivos periféricos como impresoras).
Déjame mostrarte cómo funciona la redirección y cómo puedes usarla.
La redirección de salida
La primera y más simple forma de redirección es la redirección de salida, también llamada redirección de salida estándar.
Ya sabe que, de forma predeterminada, la salida de un comando se muestra en la pantalla. Por ejemplo, uso el comando ls para enumerar todos los archivos y este es el resultado que obtengo:
[email protected]:~$ ls
appstxt new.txt static-ip.txt
Con la redirección de salida, puede redirigir la salida a un archivo. Si este archivo de salida no existe, el shell lo creará.
command > file
Por ejemplo, permítanme guardar la salida del comando ls en un archivo llamado salida.txt:
[email protected]:~$ ls > output.txt
El archivo de salida se crea de antemano
¿Cuál cree que debería ser el contenido de este archivo de salida? Déjame usar el comando gato para mostrarte una sorpresa:
[email protected]:~$ cat output.txt
appstxt
new.txt
output.txt
static-ip.txt
¿Notaste que la inclusión de output.txt allí ? Elegí deliberadamente este ejemplo para mostrarte esto.
El archivo de salida al que se redirige la salida estándar se crea antes de que se ejecute el comando deseado. ¿Por qué? Porque necesita tener listo el destino de salida al que se enviará la salida.
Añadir en lugar de clobber
Un problema que a menudo se ignora es que si redirige a un archivo que ya existe, el shell borrará (golpeará) el archivo primero. Esto significa que el contenido existente del archivo de salida será eliminado y reemplazado por la salida del comando.
Puede agregar, en lugar de sobrescribirlo, usando la>> sintaxis de redirección.
command >> file
Consejo :Puede prohibir el clobbing en la sesión de shell actual usando:set -C
¿Por qué redirigiría stdout? Puede almacenar la salida para referencia futura y analizarla más tarde. Es especialmente útil cuando la salida del comando es demasiado grande y ocupa toda la pantalla. Es como recopilar registros.
Redirección de tubería
Antes de ver la redirección de stdin, debe aprender sobre la redirección de tubería. Esto es más común y probablemente lo usarás mucho.
Con la redirección de tuberías, envía la salida estándar de un comando a la entrada estándar de otro comando.
command 1 | command 2
Déjame mostrarte un ejemplo práctico. Digamos que desea contar la cantidad de archivos visibles en el directorio actual. Puede usar ls -1 (es el número uno, no la letra L) para mostrar los archivos en el directorio actual:
[email protected]:~$ ls -1
appstxt
new.txt
output.txt
static-ip.txt
Probablemente ya sepa que el comando wc se usa para contar el número de líneas en un archivo. Si combina estos dos comandos con tubería, esto es lo que obtiene:
[email protected]:~$ ls -1 | wc -l
4
Con pipe, ambos comandos comparten el mismo búfer de memoria. La salida del primer comando se almacena en el búfer y el mismo búfer se usa como entrada para el siguiente comando.
Verá el resultado del último comando en la canalización. Eso es obvio porque la salida estándar de los comandos anteriores se envía a los siguientes comandos en lugar de ir a la pantalla.
La redirección de tuberías o tuberías no se limita a conectar solo dos comandos. Puede conectar más comandos siempre que la salida de un comando se pueda usar como entrada del siguiente comando.
command_1 | command_2 | command_3 | command_4
Recuerde que stdout/stdin es una porción de datos, no nombres de archivos
Algunos nuevos usuarios de Linux se confunden al usar la redirección. Si un comando devuelve un montón de nombres de archivo como salida, no puede usar esos nombres de archivo como argumento.
Por ejemplo, si usa el comando de búsqueda para encontrar todos los archivos que terminan en .txt, no puede pasarlo a través de una tubería para mover los archivos encontrados a un nuevo directorio, no directamente así:
find . -type f -name "*.txt" | mv destination_directory
Esta es la razón por la que a menudo verás que el comando find se usa en conjugación con el comando exec o xargs. Estos comandos especiales "convierten el texto con un montón de nombres de archivo en un nombre de archivo" que se puede pasar como argumento.
find . -type f -name "*.txt" | xargs -t -I{} mv {} ../new_dir
La redirección de entrada
Puede usar la redirección stdin para pasar el contenido de un archivo de texto a un comando como este:
command < file
No verá que stdin se use mucho. Esto se debe a que la mayoría de los comandos de Linux aceptan nombres de archivo como argumento y, por lo tanto, la redirección de entrada estándar a menudo no es necesaria.
Toma esto por ejemplo:
head < filename.txt
El comando anterior podría haber sido simplemente head filename.txt (sin <).
No es que la redirección stdin sea completamente inútil. Algunos comandos se basan en él. Tome el comando tr por ejemplo. Este comando puede hacer muchas cosas, pero en el siguiente ejemplo, convierte el texto de entrada de minúsculas a mayúsculas:
tr a-z A-Z < filename.txt
De hecho, se recomienda usar stdin sobre pipe especialmente para evitar el uso innecesario del comando cat.
Por ejemplo, mucha gente usaría el ejemplo anterior con cat y luego usaría tr en él. Francamente, no hay necesidad de usar gato aquí.
cat filename.txt | tr a-z A-Z
Combinar redirecciones
Puede combinar la redirección de entrada estándar, salida estándar y canalización según sus necesidades.
Por ejemplo, el siguiente comando enumera todos los archivos .txt en el directorio actual y luego hace un recuento de esos archivos .txt y guarda la salida en un archivo nuevo.
ls *.txt | wc -l > count.txt
Error de redirección
A veces, cuando ejecuta algún comando o secuencia de comandos, verá que muestra un mensaje de error en la pantalla.
[email protected]:~$ ls -l ffffff > output.txt
ls: cannot access 'ffffff': No such file or directory
Al comienzo de este artículo, mencioné que hay tres flujos de datos y stderr es uno de los flujos de datos de salida que se muestra en la pantalla de forma predeterminada.
También puede redirigir el stderr. Dado que es un flujo de datos de salida, puede usar el mismo símbolo de redirección> o>> que usó para la redirección de salida estándar.
Pero, ¿cómo se distingue entre stdout y stderr cuando ambos son un flujo de datos de salida? Por su ID de flujo (también llamado descriptor de archivo).
Flujo de datos | ID de transmisión |
---|---|
entrada estándar | 0 |
salida estándar | 1 |
stderr | 2 |
-t, | –lista |
-u, | –actualizar |
-x, | –extraer, –obtener |
-j, | –bzip2 |
-z, | –gzip, –gunzip, –ungzip |