GNU/Linux >> Tutoriales Linux >  >> Linux

Cómo redirigir la salida del comando de shell

Los scripts de shell brindan una característica muy poderosa:la capacidad de redirigir la salida de comandos y scripts y enviarla 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.

Tipos de salida

Los comandos y scripts en un shell pueden generar dos tipos básicos de resultados:

  • SALIDA ESTÁNDAR: La salida normal de un comando/secuencia de comandos (descriptor de archivo 1)
  • STDERR: La salida de error de un 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, STDIN por defecto lee la entrada del teclado (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 del 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 ls simple comandos para ilustrar STDOUT frente a STDERR, pero el mismo principio se aplica a la mayoría de los comandos que ejecuta desde un shell.

Puedo redirigir la salida estándar 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 con un 1 antes de > . Redirigir usando el > la señal es lo mismo que usar 1> para hacerlo:le digo al shell que redirija el STDOUT a ese archivo. Si omito el descriptor de archivo, STDOUT se usa de forma predeterminada. Puedo probar esto ejecutando sdiff comando para mostrar 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 con ls file* non-existing-file* > my_normal_output.txt :

Aquí está el resultado:

Imagen

Aquí hay algunas observaciones de la prueba anterior:

  1. El resultado de los archivos existentes se envía correctamente al archivo de destino.
  2. El error (que aparece cuando trato de enumerar algo que no existe) se envía a la pantalla. Este es el lugar predeterminado donde se envían los errores a menos que los redirija.

[ Descargue una hoja de referencia de secuencias de comandos de Bash Shell. ]

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

Imagen

En el ejemplo anterior:

  1. Los ls El comando no muestra el mensaje de error en la pantalla como antes.
  2. La salida normal contiene lo que espero.
  3. El mensaje de error se envía a my_error_output.txt archivo.

3. Enviar STDOUT y STDERR al mismo archivo

Otra situación común es enviar STDOUT y STDERR al mismo archivo:

$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.

El 2>&1 construcción significa "enviar el STDERR al mismo lugar donde está enviando el STDOUT ."

4. Redirigir la salida, pero agregar el archivo

En todos los ejemplos anteriores, cada vez que redirigía alguna salida, usaba un solo > , lo que significa "envíe algo a este archivo e inicie el archivo desde cero ." Como resultado, si el archivo de destino existe, se sobrescribe.

Si quiero añadir a un archivo existente, necesito usar >> . Si el archivo aún no existe, se creará:

$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

Los ejemplos anteriores cubren la redirección de la salida a un archivo, pero también puede redirigir las salidas a otros procesos o dev/null .

Enviar resultados a otros procesos es una de las características más poderosas de un shell. Para esta tarea, use el | (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, filtra cualquiera que contenga la cadena chrome , ignora la línea sobre mi grep y cuenta las líneas resultantes. Si quiero enviar la salida a un archivo, agrego > y un nombre de archivo al final de la cadena.

Finalmente, aquí hay un ejemplo en el que quiero ignorar una de las salidas, STDERR:

$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 el tar El comando no encontró ningún archivo con nombres que comiencen con more-non-existing , se muestran algunos mensajes de error al final.

Supongamos que creo algunos scripts y no me importa ver o capturar 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

El /dev/null es un archivo de dispositivo especial que es como un "agujero negro":lo que envía allí simplemente desaparece.

[ Descargue esta guía para instalar aplicaciones en Linux. ]

6. Usar la redirección en un script

Imagen
=== 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:ejecuta un comando en el sistema operativo y lo guarda en la variable DATE_TIME.
  • Línea 6:Ejecuta el ps comando y redirige a grep y a un archivo.
    • En lugar de enviar el resultado a un archivo, podría enviarlo a una variable (como en la línea 3), pero en este caso quiero ejecutar otras acciones usando el mismo resultado, así que lo capturo. En una situación más realista, tener el archivo también podría ser útil durante el desarrollo o la resolución de problemas, por lo que puedo investigar más fácilmente lo que genera el comando.
  • Línea 8:ejecuta comandos adicionales, redirige las salidas a wc y asigna el resultado a una variable.
  • Línea 9:Usa awk para seleccionar solo la columna 2 de la salida y ordenarla en orden descendente (solo para agregar otra tubería).

Resumir

Esos fueron algunos ejemplos de redireccionamiento de STDOUT y STDERR. Poniendo todo esto junto, te das cuenta de lo poderosa que puede ser 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 otro modo, requerirían que desarrolle un script o un programa. También podría incorporar la técnica en otros scripts, usando todo como bloques de construcción.


Linux
  1. ¿Cómo asignar la salida de un comando a una variable de shell?

  2. ¿Cómo saber si la salida de un comando o script de Shell es Stdout o Stderr?

  3. Cómo redirigir la salida a un archivo y stdout

  4. ¿Cómo agregar la salida a un archivo?

  5. ¿Cómo guardar la salida de este comando awk en un archivo?

Cómo guardar la salida del comando en un archivo en Linux

Cómo guardar la salida del comando de Linux en una imagen o un archivo de texto

Redirección de salida de comando a archivo y terminal

Cómo redirigir la salida del servicio systemd a un archivo

Cómo redirigir la salida completa de spark-submit a un archivo

¿Cómo redirigir la salida de un comando a un archivo cuando el comando solicitará las entradas del usuario?