Tutoriales

Cómo redirigir la salida del comando de shell

Los scripts de shell brindan una función muy poderosa: la capacidad de redirigir y enviar la salida de comandos y scripts a archivos, dispositivos o incluso como entrada a otros comandos o scripts.

Este artículo se centra en la salida de comandos y secuencias de comandos.

Tipo de salida

Los comandos y scripts en el shell pueden generar dos tipos básicos de salida:

  • Salida estándar: Salida normal del comando/secuencia de comandos (descriptor de archivo 1)
  • Error estándar: Salida de error del comando/secuencia de comandos (descriptor de archivo 2)

De forma predeterminada, STDOUT y STDERR se envían a la pantalla de su terminal.

En términos de entrada, entrada estándar La entrada se lee desde el teclado de forma predeterminada (descriptor de archivo 0). Un descriptor de archivo es un identificador único para un archivo u otro recurso de E/S.

Cómo redirigir la salida de shell

Hay varias formas de redirigir la salida de los scripts y comandos de shell.

1. Redirigir STDOUT

Para los siguientes ejemplos, usaré este conjunto simple de archivos:

$ls -la file*
-rw-r--r--. 1 admin2 admin2  7 Mar 27 15:34 file1.txt
-rw-r--r--. 1 admin2 admin2 10 Mar 27 15:34 file2.txt
-rw-r--r--. 1 admin2 admin2 13 Mar 27 15:34 file3.txt

estoy ejecutando un simple ls comando para ilustrar STDOUT vs STDERR, pero los mismos principios se aplican a la mayoría de los comandos que ejecuta desde el shell.

Puedo redirigir stdout a un archivo usando ls file* > my_stdout.txt:

$ls file* > my_stdout.txt

$ cat my_stdout.txt 
file1.txt
file2.txt
file3.txt

A continuación, ejecuto un comando similar, pero usando 1 delantero >Usar redirección > La señal es lo mismo que usar 1> Haciendo esto: le digo al shell que redirija STDOUT a este archivo. Si omito el descriptor de archivo, STDOUT se usa de forma predeterminada.puedo correr sdiff El comando muestra la salida de ambos comandos uno al lado del otro:

$ls file* 1> my_other_stdout.txt

$sdiff my_stdout.txt my_other_stdout.txt
file1.txt			             file1.txt
file2.txt			             file2.txt
file3.txt			             file3.txt

Como puede ver, ambas salidas tienen el mismo contenido.

2. Redirigir STDERR

Ahora, ¿qué tiene de especial STDERR?Para demostrarlo, introduciré una condición de error en el ejemplo anterior. ls file* non-existing-file* > my_normal_output.txt:

El resultado es el siguiente:

(Roberto Nozaki, CC BY-SA 4.0)

Aquí hay algunas observaciones de la prueba anterior:

  1. La salida de los archivos existentes se enviará correctamente al archivo de destino.
  2. Se envía a la pantalla un error (que se muestra cuando intento enumerar algo que no existe). Aquí es donde se envían los errores de forma predeterminada, a menos que los redirija.

[ Download a Bash Shell Scripting Cheat Sheet. ]

A continuación, redirigiré la salida de error haciendo referencia explícita al descriptor de archivo 2 ls file* non-existing-file* > my_normal_output.txt 2> my_error_output.txt:

(Roberto Nozaki, CC BY-SA 4.0)

En el ejemplo anterior:

  1. este ls Los comandos no muestran mensajes de error en la pantalla como antes.
  2. La salida normal contiene lo que esperaría.
  3. Los mensajes de error se envían a my_error_output.txt documento.

3. Enviar STDOUT y STDERR al mismo archivo

Otra situación común es enviar STDOUT y STDERR a idéntico documento:

$ls file* non-existing-file* > my_consolidated_output.txt 2>&1

$ cat my_consolidated_output.txt 
ls: cannot access 'non-existing-file*': No such file or directory
file1.txt
file2.txt
file3.txt

En este ejemplo, toda la salida (normal y de error) se envía al mismo archivo.

este 2>&1 medios de construcción»Envía STDERR al mismo lugar que enviaste STDOUT. «

4. Redirigir la salida, pero agregar archivos

En todos los ejemplos anteriores, cada vez que redirijo alguna salida, uso un >el significado es»Envíe algo a este archivo e inicie el archivo desde cero.» Entonces, si el archivo de destino existe, se sobrescribirá.

Si yo quiero adicional a un archivo existente, necesito usar >>El archivo se crea si aún no existe:

$echo "Adding stuff to the end of a file" >> my_output.txt

$cat my_output.txt 
file1.txt
file2.txt
file3.txt
Adding stuff to the end of a file

5. Redirigir a otro proceso o a ninguna parte

El ejemplo anterior cubre la redirección de la salida a un archivo, pero también puede redirigir la salida a otros procesos o dev/null.

Enviar resultados a otros procesos es una de las características más poderosas del shell.Para esta tarea, utilice | (tubería), que envía la salida de un comando a la entrada del siguiente comando:

ps -ef | grep chrome | grep -v grep | wc -l
21

El ejemplo anterior enumera mis procesos, filtrando cualquier proceso que contenga la cadena Aleación de cromoignora la linea sobre mi grep y cuente las filas resultantes.Si quiero enviar la salida a un archivo, agrego > y nombre de archivo hasta el final de la cadena.

Finalmente, aquí hay un ejemplo en el que quiero ignorar uno de los STDERR de salida:

$tar cvf my_files.tar file* more-non-existing*
file1.txt
file2.txt
file3.txt
tar: more-non-existing*: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

porque tar El comando no encontró ningún archivo cuyo nombre comience con more-non-existingy finalmente se muestran algunos mensajes de error.

Supongamos que creo algunos scripts y no me importa ver o detectar estos errores (lo sé, en la vida real, debe prevenir y manejar los errores, no solo ignorarlos):

$tar cvf my_files.tar file* more-non-existing* 2> /dev/null
file1.txt
file2.txt
file3.txt

este /dev/null es un archivo de dispositivo especial, como un «agujero negro»: lo que envías allí desaparece.

[ Download this guide to installing applications on Linux. ]

6. Uso de redireccionamientos en scripts

(Roberto Nozaki, CC BY-SA 4.0)
=== SUMMARY OF INVESTIGATION OF chrome ===
Date/Time of the execution: 2022-03-25 18:05:50
Number of processes found.: 5
PIDs:
1245475
1249558
1316941
1382460
1384452

Este script muy simple hace lo siguiente:

  • Línea 3: el comando se ejecuta en el sistema operativo y se guarda en la variable DATE_TIME.
  • Línea 6: Ejecutar ps ordenar y redirigir a grep y un archivo.
    • En lugar de enviar la salida a un archivo, podría enviar la salida a una variable (como la línea 3), pero en este caso quiero ejecutar otras operaciones con la misma salida, así que la capturo. En una situación más realista, tener ese archivo también es útil durante el desarrollo o la resolución de problemas para que pueda investigar más fácilmente lo que genera el comando.
  • Línea 8: Ejecute el comando adicional, redirigiendo la salida a wcy asigne el resultado a una variable.
  • Línea 9: Propósito awk Seleccione solo la columna 2 de la salida y ordénela en orden descendente (solo para agregar otra tubería).

envolver

Estos son algunos ejemplos de redireccionamiento de STDOUT y STDERR. Póngalo todo junto y se dará cuenta del poder de la redirección. Al encadenar comandos individuales, manipular su salida y usar el resultado como entrada para el siguiente comando, puede realizar tareas que, de lo contrario, podrían requerir que desarrolle un script o un programa. También puede incorporar esta técnica en otros scripts, usando todo como bloques de construcción.

LEER  Cómo crear y ejecutar un script Perl en Ubuntu 22.04 LTS

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba