Programar canales y streams, redirección. Redirigir flujos de entrada/salida estándar

Cualquier programa es una "máquina automática" diseñada para procesar datos: al recibir una información como entrada, produce otra como resultado de su trabajo. Aunque la información entrante y/o saliente puede ser nula, es decir, simplemente ausente. Los datos que se transfieren al programa para su procesamiento son su entrada, lo que produce como resultado del trabajo es la salida. Organizar la entrada y salida de cada programa es tarea del sistema operativo.

Cada programa trabaja con datos de un determinado tipo: texto, gráficos, sonido, etc. Como probablemente ya haya quedado claro, la interfaz principal de administración del sistema en Linux es una terminal, que está diseñada para transferir información de texto del usuario al sistema y atrás. Dado que sólo se puede ingresar y emitir información de texto desde el terminal, la entrada y salida de los programas asociados con el terminal también deben ser texto. Sin embargo, la necesidad de trabajar con datos de texto no limita las capacidades de gestión del sistema, sino que, por el contrario, las amplía. Una persona puede leer el resultado de cualquier programa y descubrir qué está sucediendo en el sistema, y ​​diferentes programas resultan compatibles entre sí porque utilizan el mismo tipo de representación de datos: texto.

Los comandos y scripts pueden recibir entradas de dos maneras: desde una entrada estándar (vinculada al teclado) o desde un archivo. Existe una separación similar para la salida: la salida de un comando o script se envía a la pantalla del terminal de forma predeterminada, pero puede redirigirla a un archivo. Si ocurren errores durante la operación. Los mensajes sobre ellos también se muestran en la pantalla y el flujo de errores también se puede redirigir a un archivo.

Primero veamos un par de comandos que se pueden usar para organizar E/S.

Comandos de salida al dispositivo de salida estándar

Linux proporciona varios comandos para imprimir mensajes en la salida estándar:

  • echo: imprime una cadena en la salida estándar.
  • printf: imprime texto formateado en salida estándar.
  • sí: imprime texto repetido en la salida estándar.
  • seq: imprime una secuencia de números en la salida estándar
  • clear Limpia la pantalla o ventana.

Por ejemplo, cuando se utiliza el comando echo, si especifica el carácter de control \c, cuando se complete la salida, no habrá transición a una nueva línea:

$ echo "¿Cuál es tu nombre?\c"

¿Cuál es tu nombre?$

Aquí $ es el símbolo de invitación.

La línea también puede calcular los valores de las variables del shell e incluso otros comandos. Por ejemplo, el siguiente comando le indica cuál es el directorio de inicio del usuario actual (la variable de entorno $HOME) y a qué terminal está conectado (el comando tty está entre comillas para que el intérprete coloque el resultado de su ejecución en un línea).

$ echo "Su directorio de inicio es $HOME, está conectado al terminal - `tty` "

Su directorio de inicio es /home/knoppix, está conectado al terminal - /dev/tty1

Dado que las comillas dobles tienen un propósito especial en el intérprete de shell, para incluir comillas dobles en la cadena de salida, debe deshacer su propósito especial usando una barra invertida (\). Esto cancela la asignación de cualquier carácter especial.

Por ejemplo, para mostrar la cadena "/dev/tty1" necesita ejecutar:

$echo “\”/dev/tty1\””

Comandos de entrada desde un dispositivo de entrada estándar

El comando de lectura lee una línea de la entrada estándar y escribe su contenido en las variables especificadas. Al especificar varias variables, la primera palabra se escribe en la primera, la segunda palabra en la segunda, etc. el último contiene el resto de la línea.

El siguiente script llama a un comando de lectura independiente para leer cada variable.


$ prueba de gato
#!/bin/bash
eco “Nombre: \c”
leer nombre
echo “Apellido: \c”
leer apellido
echo “Nombre=” $nombre “Apellido=” $apellido

Luego, para ejecutar este script, debe darle al archivo de prueba el derecho de ejecución: chmod 0755 test y ejecutarlo./test. Resultado de la ejecución: Nombre: Ivan Apellido: Petrov Nombre=Ivan Apellido=Petrov

ENTRADA ESTÁNDAR, SALIDA Y FLUJO DE ERRORES

Cada programa iniciado desde el intérprete de comandos recibe tres flujos de E/S abiertos:

Entrada estándar (sldin) - salida estándar (sldout) - salida de error estándar (stderr)

De forma predeterminada, estos subprocesos están asociados con el terminal. Aquellos. Cualquier programa que no utilice secuencias distintas a las estándar esperará la entrada del teclado del terminal; todos los resultados de ese programa, incluidos los mensajes de error, se producirán en la pantalla del terminal.

Además, cada proceso (comando, script, etc.) ejecutado en el intérprete de shell está asociado con una serie de archivos abiertos desde los cuales el proceso puede leer sus datos y en los que puede escribirlos. Cada uno de estos archivos se identifica mediante un número llamado descriptor de archivo, pero los primeros tres archivos son los flujos de E/S predeterminados:

Descriptor de archivo
Entrada estándar 0
Salida estándar 1
Flujo de error estándar 2

En realidad, se crean 12 archivos abiertos, pero los archivos con los descriptores 0, 1 y 2 están reservados para entrada, salida y error estándar. Los usuarios también pueden trabajar con archivos que tengan descriptores de archivo del 3 al 9 (reservados).

El archivo de entrada estándar (sldin) tiene el identificador 0. De este archivo, los procesos extraen sus datos de entrada. De forma predeterminada, el flujo de entrada está asociado con el teclado (dispositivo /dev/tty), pero la mayoría de las veces proviene de una tubería desde otros procesos o desde un archivo normal.

El archivo de salida estándar (stdout) tiene el identificador 1. Toda la salida del proceso se escribe en este archivo. De forma predeterminada, los datos se envían a la pantalla del terminal (dispositivo/dev/tty), pero también se pueden redirigir a un archivo o canalizar a otro proceso.

El archivo de secuencia de errores estándar (siderr) tiene el descriptor 2. Los mensajes de error que ocurren durante la ejecución del comando se escriben en este archivo. De forma predeterminada, los mensajes de error se envían a la pantalla del terminal (dispositivo /dev/tty), pero también se pueden redirigir a un archivo. ¿Por qué asignar un archivo especial para registrar errores? El hecho es que esta es una manera muy conveniente de aislar los datos de salida reales de los resultados del trabajo de un comando, así como una buena oportunidad para organizar efectivamente el mantenimiento de varios tipos de archivos de registro.

Una gran cantidad de empresas de servicios públicos utilizan únicamente flujos estándar. Para tales programas, el shell permite redirigir los flujos de E/S de forma independiente. Por ejemplo, puede suprimir mensajes de error, configurar la entrada o salida de un archivo.

Aquellos. Al llamar comandos, puede especificar dónde se deben recibir las entradas y dónde se deben enviar las salidas, así como los mensajes de error. De forma predeterminada, a menos que se especifique lo contrario, se supone que se trabaja con un terminal: los datos se ingresan desde el teclado y se muestran en la pantalla. Pero el intérprete de shell tiene un mecanismo de redirección que permite asociar secuencias estándar con diferentes archivos. En este caso, al redirigir el flujo de error estándar, se debe especificar un descriptor de archivo (2). Esto no es necesario para los flujos de entrada y salida.

Un caso especial útil de uso del mecanismo de redirección de hilos es redirigir a /dev/null, lo que le permite deshacerse de mensajes innecesarios en la pantalla. Usando el mismo mecanismo, puedes crear archivos vacíos:

% cat myfile: creará un archivo vacío myfile en el directorio actual.

/dev/null es un archivo especial llamado. "dispositivo vacío" La escritura en él se realiza con éxito, independientemente de la cantidad de información "registrada". Leer desde /dev/null equivale a leer el final del archivo EOF.

Redirigir flujos de E/S se lleva a cabo, como DOS (Más precisamente, el sistema operativo DOS adoptó la sintaxis para redirigir transmisiones desde UNIX) usando los símbolos:

- redirigir el flujo de salida estándar
- redirección del flujo de salida estándar en modo agregar
- redirigir el flujo de entrada estándar
- recibir datos de la entrada estándar hasta que se encuentre un delimitador

Sin embargo, a diferencia de DOS, al crear un canal de programa entre dos procesos, el sistema operativo UNIX/Linux inicia ambos procesos simultáneamente y transfiere información a través del búfer del sistema (sin grabación intermedia en el disco duro). Por tanto, los canales de software en los sistemas operativos UNIX/Linux son una forma de intercambio muy eficaz. Si el buffer del sistema se desborda (por ejemplo, si el programa "enviador" envía información al canal más rápido de lo que el programa "receptor" puede procesarla), el sistema operativo suspende automáticamente el proceso que escribe en el canal hasta que el buffer se desborda. es liberado.

Operadores de redireccionamiento más comunes

No. Sintaxis Descripción
1 archivo de comando Dirige la salida estándar a un archivo nuevo

2 comando 1 archivo Dirige la salida estándar al archivo especificado

Comando de 3 archivos Dirige la salida estándar al archivo especificado (modo adjuntar)

4 archivo de comando 2 y 1 Dirige la salida estándar y los errores al archivo especificado

5 comando 2 archivo Dirige el error estándar al archivo especificado

6 comando 2 archivo Dirige el error estándar al archivo especificado (modo agregar)

7 archivo de comando 2 y 1 Dirige la salida estándar y el error al archivo especificado (modo adjuntar)

8 comando archivo1 archivo2 Recibe la entrada del primer archivo y envía la salida al segundo archivo

9 archivo de comando como entrada estándar recibe datos del archivo especificado

10 comando delimitador Recibe datos de la entrada estándar hasta que se encuentra un delimitador

11 comando &m Recibe datos de un archivo con el descriptor m como entrada estándar

12 comando &m Dirige la salida estándar al descriptor de archivo m

El operador n&m permite redirigir un archivo con el descriptor n a la misma ubicación que un archivo con el descriptor m. Puede haber varios operadores similares en la línea de comando, en cuyo caso se calculan de izquierda a derecha.

comando ejecutivo y uso de descriptores de archivos

El comando exec reemplaza el shell actual con el comando especificado. Normalmente se utiliza para cerrar el intérprete actual e iniciar otro. Pero también tiene otros usos.

Por ejemplo, un comando como

El archivo Exec convierte el archivo especificado en la entrada estándar de todos los comandos. Realizarlo en
no tiene sentido el modo interactivo: está diseñado para su uso en scripts,
para que todos los comandos que vienen después lean sus datos de entrada del archivo. En este caso
debe haber un comando al final del script

Exec &: que cierra el flujo de entrada estándar (en este caso un archivo). Se utiliza una técnica similar
principalmente en scripts que se ejecutan cuando cierras la sesión.

El comando exec es un puntero a un archivo con descriptor 0 (stdin). Este puntero se puede restaurar solo después de que el script haya terminado de ejecutarse.
Si el script pretende continuar leyendo datos desde el teclado, entonces debe guardar
puntero al flujo de entrada anterior. A continuación se muestra un breve guión que demuestra cómo hacer esto.

$ gato f_desc
#!/bin/bash
ejecutivo 3 y 0 0 archivo
leer linea
leer linea2
ejecutivo 0 y 3
eco $1inel
eco $linea2

El primer comando exec almacena un puntero al flujo de entrada estándar (stdin) en el descriptor de archivo 3
(se permite cualquier número entero entre 3 y 9) y luego abre el archivo para leerlo. Los siguientes dos comandos de lectura
leer dos líneas de texto de un archivo. El segundo comando exec restaura el puntero a la entrada estándar: ahora
está asociado con el archivo stdin, no con el archivo. Los comandos de eco finales muestran el contenido de las líneas leídas en la pantalla,
que se almacenaron en las variables linel e Iine2.

El resultado del guión:
$./f_desc
¡Hola!
¡Adiós!

Aprendiendo Linux, 101

Streams, canales de programas y redirecciones

Aprender los conceptos básicos de las canalizaciones de Linux

Serie de contenido:

Breve reseña

En este artículo, aprenderá las técnicas básicas para redirigir flujos de E/S estándar en Linux. Aprenderás:

  • Redirigir flujos de entrada/salida estándar: entrada estándar, salida estándar y error estándar.
  • Dirija la salida de un comando a la entrada de otro comando.
  • Envíe la salida al dispositivo de salida estándar (stdout) y a un archivo simultáneamente.
  • Utilice la salida de un comando como argumento para otro comando.

Este artículo lo ayudará a prepararse para tomar el examen LPI 101 Entry Level Administrator (LPIC-1) y contiene material del Objetivo 103.4 del Tema 103. El objetivo tiene un peso de 4.

Acerca de esta serie

Esta serie de artículos le ayudará a dominar las tareas de administración del sistema operativo Linux. También puede utilizar el material de estos artículos para prepararse.

Para ver descripciones de los artículos de esta serie y obtener enlaces a ellos, consulte nuestro. Esta lista se actualiza continuamente con nuevos artículos a medida que están disponibles y contiene los objetivos del examen de certificación LPIC-1 más actualizados (a abril de 2009). Si falta un artículo en la lista, puede encontrar una versión anterior que cumpla con los objetivos anteriores de LPIC-1 (antes de abril de 2009) consultando nuestro .

Las condiciones necesarias

Para aprovechar al máximo nuestros artículos, debe tener conocimientos básicos de Linux y tener una computadora con Linux que funcione y que pueda ejecutar todos los comandos que encuentre. A veces, diferentes versiones de programas producen resultados diferentes, por lo que el contenido de los listados y las figuras puede diferir de lo que ve en su computadora.

Preparación para ejecutar los ejemplos

Cómo contactar a Ian

Ian es uno de nuestros autores más populares y prolíficos. Consulte (EN) publicado en desarrolladorWorks. Puede encontrar información de contacto y conectarse con él y otros colaboradores y colaboradores de My DeveloperWorks.

Para ejecutar los ejemplos de este artículo, utilizaremos algunos de los archivos creados anteriormente en el " " artículo. Si no ha leído este artículo ni ha guardado estos archivos, ¡no se preocupe! Comencemos creando un nuevo directorio lpi103-4 y todos los archivos necesarios. Para hacer esto, abra una ventana de texto y navegue hasta su directorio de inicio. Copie el contenido del Listado 1 en el cuadro de texto; como resultado de ejecutar los comandos, el subdirectorio lpi103-4 y todos los archivos necesarios que contiene se crearán en su directorio de inicio, que usaremos en nuestros ejemplos.

Listado 1. Creación de los archivos necesarios para los ejemplos de este artículo.
mkdir -p lpi103-4 && cd lpi103-4 && ( echo -e "1 manzana\n2 pera\n3 plátano" > text1 echo -e "9\tplum\n3\tbanana\n10\tapple" > text2 echo "Esto es una oración " !#:* !#:1->text3 dividir -l 2 texto1 dividir -b 17 texto2 y; )

Su ventana debería verse como el Listado 2 y su directorio de trabajo actual debería ser el directorio lpi103-4 recién creado.

Listado 2. Resultados de la creación de los archivos necesarios
$ mkdir -p lpi103-4 && cd lpi103-4 && ( > echo -e "1 manzana\n2 pera\n3 plátano" > texto1 > echo -e "9\tplum\n3\tbanana\n10\tapple" > texto2 > echo "Esto es una oración." !#:* !#:1->text3echo "Esto es una oración." "Esto es una oración.">text3 > split -l 2 text1 > split -b 17 texto2 y ) $

Redirigir entrada/salida estándar

Un shell de Linux, como Bash, recibe entradas y envía salidas en forma de secuencias o corrientes caracteres. Cualquier personaje es independiente de los personajes anteriores o posteriores. Los símbolos no están organizados en entradas estructuradas ni bloques de tamaño fijo. Se accede a las secuencias mediante mecanismos de E/S independientemente de dónde provienen o a dónde se envían las secuencias de caracteres (un archivo, teclado, ventana, pantalla u otro dispositivo de E/S). Los shells de Linux utilizan tres flujos de E/S estándar, a cada uno de los cuales se le asigna un descriptor de archivo específico.

  1. salida estándarsalida estándar, muestra la salida del comando y tiene el identificador 1.
  2. stderrflujo de error estándar, muestra errores de comando y tiene el descriptor 2.
  3. entrada estándarentrada estándar, pasa entrada a comandos y tiene el identificador 0.

Los flujos de entrada proporcionan información (normalmente desde el teclado) para los comandos. Los flujos de salida proporcionan impresión de caracteres de texto, normalmente a una terminal. El terminal era originalmente un dispositivo de impresión ASCII o un terminal de visualización, pero ahora suele ser solo una ventana en el escritorio de la computadora.

Si ya ha leído la guía "", parte del material de este artículo le resultará familiar.

Redirección de salida

Hay dos formas de redirigir la salida a un archivo:

norte> redirige la salida de un descriptor de archivo norte archivar. Debe tener permisos de escritura en el archivo. Si el archivo no existe, se creará. Si el archivo existe, entonces todo su contenido generalmente se destruye sin previo aviso. norte>> también redirige la salida del descriptor de archivo norte archivar. También debe tener permisos de escritura en el archivo. Si el archivo no existe, se creará. Si el archivo existe, la salida se adjunta a su contenido.

Símbolo norte en los operadores n> o n>> es descriptor de archivo. Si no se especifica, se supone que se utiliza el dispositivo de salida estándar. El Listado 3 demuestra la operación de redirección para separar la salida estándar y el error estándar del comando ls, utilizando archivos que se crearon anteriormente en el directorio lpi103-4. También se demuestra cómo agregar salida de comando a archivos existentes.

Listado 3. Redirección de salida
$ ls x* z* ls: no puede acceder a z*: no existe tal archivo o directorio xaa xab $ ls x* z* >stdout.txt 2>stderr.txt $ ls w* y* ls: no puede acceder a w*: no existe archivo o directorio yaa yab $ ls w* y* >>stdout.txt 2>>stderr.txt $ cat stdout.txt xaa xab yaa yab $ cat stderr.txt ls: no puedo acceder z*: No existe tal archivo o directorio ls: no puedo acceder a w*: No existe tal archivo o directorio

Ya hemos dicho que redirigir la salida usando el operador n> generalmente resulta en la sobrescritura de los archivos existentes. Puede controlar esta propiedad utilizando la opción noclobber del comando integrado set. Si esta opción está definida, puede anularla usando el operador n>|, como se muestra en el Listado 4.

Listado 4. Redirigir la salida usando la opción noclobber
$ set -o noclobber $ ls x* z* >stdout.txt 2>stderr.txt -bash: stdout.txt: no se puede sobrescribir el archivo existente $ ls x* z* >|stdout.txt 2>|stderr.txt $ cat stdout.txt xaa xab $ cat stderr.txt ls: no puedo acceder z*: No existe tal archivo o directorio $ set +o noclobber #restaurar la configuración original de noclobber

A veces es posible que desee redirigir tanto la salida estándar como el error estándar a un archivo. Esto se suele utilizar en procesos automatizados o trabajos en segundo plano para que los resultados del trabajo se puedan revisar más adelante. Para redirigir la salida estándar y el error estándar a la misma ubicación, utilice el operador &> o &>>. La opción alternativa es redirigir el descriptor del archivo. norte y luego el descriptor del archivo metro al mismo lugar usando la construcción m>&n o m>>&n. En este caso, el orden en el que se redirigen los hilos es importante. Por ejemplo, el comando
comando 2>&1>salida.txt
no es lo mismo que un comando
comando >salida.txt 2>&1
En el primer caso, la secuencia de error stderr se redirige a la ubicación actual de la secuencia stdout y luego la secuencia stdout se redirige al archivo output.txt; sin embargo, la segunda redirección solo afecta a stdout y no a stderr. En el segundo caso, la secuencia stderr se redirige a la ubicación actual de la secuencia stdout, es decir, al archivo output.txt. Estas redirecciones se ilustran en el Listado 5. Observe en el último comando que la salida estándar se redirigió después del flujo de error estándar y, como resultado, el flujo de error continúa enviándose a la ventana del terminal.

Listado 5. Redirigir dos transmisiones a un archivo
$ ls x* z* &>output.txt $ cat output.txt ls: no puedo acceder a z*: No existe tal archivo o directorio xaa xab $ ls x* z* >output.txt 2>&1 $ cat output.txt ls: no puedo acceder a z*: no existe tal archivo o directorio xaa xab $ ls x* z* 2>&1 >output.txt # stderr no va a salida.txt ls: no puedo acceder a z*: no existe tal archivo o directorio $ cat salida. txt xaa xab

En otras situaciones, es posible que desee ignorar por completo la salida estándar o el error estándar. Para hacer esto, redirija la secuencia correspondiente al archivo vacío /dev/null. El Listado 6 muestra cómo ignorar el flujo de error ls y cómo usar el comando cat para verificar que /dev/null esté vacío.

Listado 6. Ignorar el error estándar usando /dev/null
$ ls x* z* 2>/dev/null xaa xab $ cat /dev/null

Redirección de entrada

Así como podemos redirigir stdout y stderr, podemos redirigir stdin desde un archivo usando el operador<. Если вы прочли руководство " ", то должны помнить, что в разделе была использована команда tr для замены пробелов в файле text1 на символы табуляции. В том примере мы использовали вывод команды cat чтобы создать стандартный поток ввода для команды tr . Теперь для преобразования пробелов в символы табуляции вместо бесполезного вызова команды cat мы можем использовать перенаправление ввода, как показано в листинге 7.

Listado 7. Redirección de entrada
$tr " " "\t"

Los intérpretes de comandos, incluido bash, implementan el concepto aqui-documento, que es una de las formas de redirigir la entrada. Utiliza el diseño<< и какое-либо слово, например END, являющееся маркером, или сигнальной меткой, означающей конец ввода. Эта концепция продемонстрирована в листинге 8.

Listado 8. Redirigir la entrada usando el concepto de documento aquí
$ ordenar -k2<1 manzana > 2 pera > 3 plátano > FINAL 1 manzana 3 plátano 2 pera

Pero, ¿por qué no puedes simplemente escribir el comando sort -k2, ingresar los datos y presionar la combinación? Ctrl-d, indicando el final de la entrada? Por supuesto, podría ejecutar este comando, pero entonces no conocería el concepto de documento aquí, que es muy común en los scripts de shell (donde no hay otra forma de especificar qué líneas deben aceptarse como entrada). Dado que las tabulaciones se utilizan ampliamente en los scripts para alinear el texto y hacerlo más fácil de leer, existe otra técnica para utilizar el concepto de documento aquí. Cuando se utiliza el operador<<- вместо оператора << начальные символы табуляции удаляются.

En el Listado 9, utilizamos la sustitución de comandos para crear un carácter de tabulación y luego creamos un pequeño script de shell que contiene dos comandos cat, cada uno de los cuales lee datos del bloque aquí-documento. Observe que usamos la palabra FIN para señalar el bloque de documento aquí que estamos leyendo desde la terminal. Si usáramos esta misma palabra en nuestro guión, nuestra entrada terminaría prematuramente. Por lo tanto, en lugar de la palabra FIN, usamos la palabra EOF en el script. Una vez creado nuestro script, usamos el comando. (punto) para ejecutarlo en el contexto del shell actual.

Listado 9. Redirigir la entrada usando el concepto de documento aquí
$ ht=$(echo -en "\t") $ gato<ex-here.sh > gato<<-EOF >manzana > EOF > $(ht)gato<<-EOF >$(ht)pera > $(ht)EOF > END $ gato ex-here.sh gato<<-EOF apple EOF cat <<-EOF pear EOF $ . ex-here.sh apple pear

En futuros artículos de esta serie, aprenderá más sobre la sustitución de comandos y las secuencias de comandos. Los enlaces a todos los artículos de esta serie se pueden encontrar en.

Creando tuberías

Usando el comando xargs

El comando xargs lee datos del dispositivo de entrada estándar y luego construye y ejecuta comandos que toman la entrada recibida como parámetros. Si no se especifica ningún comando, se utiliza el comando echo. El Listado 12 muestra un ejemplo sencillo del uso de nuestro archivo text1, que contiene tres líneas de dos palabras cada una.

Listado 12. Usando el comando xargs
$ cat text1 1 manzana 2 pera 3 plátano $ xargs

¿Por qué entonces la salida de xargs contiene solo una línea? De forma predeterminada, xargs divide la entrada si encuentra caracteres delimitadores y cada fragmento resultante se convierte en un parámetro independiente. Sin embargo, cuando xargs crea un comando, se le pasan tantos parámetros como sea posible a la vez. Este comportamiento se puede cambiar usando la opción –n o --max-args. El Listado 13 muestra un ejemplo de ambas opciones; También se realizó una llamada explícita al comando echo para usar con xargs.

Listado 13. Usando comandos xargs y echo
$xargs " args > 1 manzana 2 pera 3 plátano $ xargs --max-args 3 " args > 1 manzana 2 args > pera 3 plátano $ xargs -n 1 " argumentos > 1 argumentos > argumentos de manzana > 2 argumentos > argumentos de pera > 3 argumentos > plátano

Si la entrada contiene espacios pero está entre comillas simples o dobles (o los espacios se escapan mediante barras invertidas), entonces xargs no la dividirá en partes separadas. Esto se muestra en el Listado 14.

Listado 14. Usando el comando xargs y comillas
$ echo ""4 ciruela"" | cat text1 - 1 manzana 2 pera 3 plátano "4 ciruela" $ echo ""4 ciruela"" | texto de gato1 - | xargs -n 1 1 manzana 2 pera 3 plátano 4 ciruela

Hasta ahora, todos los argumentos se han agregado al final del comando. Si necesita agregar otros argumentos opcionales después de ellos, use la opción -I para especificar una cadena de reemplazo. En el punto del comando llamado a través de xargs donde se usa la cadena de reemplazo, se sustituirá un argumento. Con este enfoque, sólo se pasa un argumento a cada comando. Sin embargo, el argumento se creará a partir de la cadena de entrada completa, en lugar de un fragmento separado de la misma. También puede usar la opción -L del comando xargs, lo que hará que se use la cadena completa como argumento, en lugar de partes individuales separadas por espacios. El uso de la opción -I implícitamente hace que se utilice la opción -L 1. El Listado 15 muestra ejemplos del uso de las opciones -I y –L.

Listado 15. Usando el comando xargs y líneas de entrada
$ xargs -I XYZ echo "INICIO XYZ REPETIR FINAL XYZ" " <9 plum> <3 banana><3 banana> <10 apple><10 apple>$ gato texto1 texto2 | xargs -L2 1 manzana 2 pera 3 plátano 9 ciruela 3 plátano 10 manzana

Aunque nuestros ejemplos utilizan archivos de texto simples, no suele utilizar el comando xargs en tales casos. Normalmente, trabajará con una gran lista de archivos resultantes de comandos como ls, find o grep. El Listado 16 muestra una forma de pasar xargs una lista del contenido de un directorio a un comando como grep.

Listado 16. Usando el comando xargs y la lista de archivos
$ ls |xargs grep "1" texto1:1 texto de manzana2:10 manzana xaa:1 manzana yaa:1

En el último ejemplo, ¿qué sucede si uno o más nombres de archivos contienen espacios? Si intenta utilizar el comando como en el Listado 16, obtendrá un error. En una situación real, es posible que la lista de archivos no se obtenga mediante el comando ls, sino, por ejemplo, como resultado de la ejecución de un script o comando de usuario; o quizás desee procesarlo en otras etapas del proceso para realizar un filtrado adicional. Por lo tanto, no tomamos en cuenta el hecho de que simplemente podría usar grep "1" * en lugar de la estructura lógica existente.

En el caso del comando ls, puede usar la opción --quoting-style para forzar que los nombres de archivos que contienen espacios estén entre paréntesis (o con escape). Una mejor solución (cuando sea posible) es utilizar la opción -0 del comando xargs, que hace que se utilicen caracteres vacíos (\0) para separar los argumentos de entrada. Aunque el comando ls no tiene la opción de utilizar nombres de archivos terminados en nulo como salida, muchos comandos pueden hacer esto.

En el Listado 17, primero copiaremos el archivo text1 al "texto 1" y luego daremos algunos ejemplos del uso de una lista de nombres de archivos que contienen espacios con el comando xargs. Estos ejemplos le ayudarán a comprender la idea, ya que puede que no sea tan fácil dominar completamente el trabajo con xargs. En particular, el último ejemplo de conversión de nuevas líneas en caracteres vacíos no funcionaría si algunos nombres de archivos ya contuvieran nuevas líneas. En la siguiente sección de este artículo, veremos una solución más sólida, utilizando el comando buscar para generar una salida adecuada que utilice caracteres nulos como delimitadores.

Listado 17. Usando el comando xargs y archivos que contienen espacios en sus nombres
$ cp text1 "texto 1" $ ls *1 |xargs grep "1" # error text1:1 apple grep: texto: No existe tal archivo o directorio grep: 1: No existe tal archivo o directorio $ ls --quoting-style escape * 1 texto1 texto\ 1 $ ls --quoting-style shell *1 text1 "text 1" $ ls --quoting-style shell *1 |xargs grep "1" texto1:1 texto de manzana 1:1 manzana $ # Ilustrar -0 opción de xargs $ ls *1 | tr "\n" "\0" |xargs -0 grep "1" texto1:1 manzana texto 1:1 manzana

El comando xargs no puede crear comandos arbitrariamente largos. Así, en Linux, hasta la versión 2.26.3 del kernel, la longitud máxima de los comandos era limitada. Si intenta ejecutar un comando como rm somepath/* y el directorio contiene muchos archivos con nombres largos, puede fallar con un error que indique que la lista de argumentos es demasiado larga. Si está ejecutando versiones anteriores de Linux o UNIX que pueden tener estas limitaciones, podría ser útil saber cómo puede usar xargs para evitarlas.

Puede usar la opción --show-limits para ver los límites predeterminados para el comando xargs y la opción -s para establecer la longitud máxima de los comandos mostrados. Puede conocer otras opciones en las páginas de manual.

Usando el comando buscar con la opción -exec o junto con el comando xargs

En el " " tutorial, aprendió a utilizar el comando de búsqueda para buscar archivos según su nombre, hora de modificación, tamaño y otras características. Por lo general, se deben realizar ciertas acciones en los archivos encontrados: eliminarlos, copiarlos, cambiarles el nombre, etc. Ahora veremos la opción -exec del comando buscar, que funciona de manera similar al comando buscar y luego pasa la salida al comando xargs.

Listado 18. Usando buscar con la opción -exec
$ buscar texto -exec cat text3()\; Esta es una frase. Esta es una frase. Esta es una frase. 1 manzana 2 pera 3 plátano Esta es una oración. Esta es una frase. Esta es una frase. 9 ciruela 3 plátano 10 manzana

Comparar los resultados del Listado 18 con lo que ya sabes sobre xargs revela algunas diferencias.

  1. debe use los símbolos () en el comando para indicar la ubicación de sustitución donde se sustituirá el nombre del archivo. Estos caracteres no se agregan automáticamente al final del comando.
  2. Debe finalizar el comando con un punto y coma, que debe tener carácter de escape (\;, ";" o ";").
  3. El comando se ejecuta una vez para cada archivo de entrada.

Intente ejecutar find text |xargs cat text3 usted mismo para ver las diferencias.

Ahora volvamos al caso en el que el nombre del archivo contiene espacios. En el Listado 19, intentamos usar el comando buscar con la opción -exec en lugar de los comandos ls y xargs.

Listado 19. Usando el comando buscar con la opción -exec y archivos que contienen espacios en sus nombres
$ encontrar. -nombre "*1" -exec grep "1" () \; 1 manzana 1 manzana

Hasta ahora, todo bien. Sin embargo, ¿no crees que aquí falta algo? ¿Qué archivos contenían las líneas encontradas por grep? Lo que falta aquí son los nombres de los archivos porque find llama a grep una vez para cada archivo, y grep, al ser un comando inteligente, sabe que si solo se le dio el nombre de un archivo, no necesita decirle qué archivo era.

En esta situación, podríamos usar el comando xargs, pero ya conocemos el problema con los archivos cuyos nombres contienen espacios. También mencionamos el hecho de que el comando de búsqueda puede generar una lista de nombres delimitada por nulos gracias a la opción -print0. Las versiones modernas del comando de búsqueda se pueden separar no con un punto y coma, sino con un signo +, de modo que se pueda pasar la máxima cantidad posible de nombres en una llamada al comando de búsqueda, como cuando se usa xargs. No hace falta decir que en este caso solo puedes usar la construcción () una vez y que debe ser el último parámetro del comando. El Listado 20 demuestra ambos métodos.

Listado 20. Usando find , xargs y archivos que contienen espacios en sus nombres
$ encontrar. -name "*1" -print0 |xargs -0 grep "1" ./text 1:1 manzana ./text1:1 manzana $ buscar . -nombre "*1" -exec grep "1" () + ./text 1:1 manzana ./text1:1 manzana

Ambos métodos funcionan y la elección de uno de ellos suele estar determinada únicamente por las preferencias personales del usuario. Tenga en cuenta que puede tener problemas al canalizar objetos con delimitadores sin formato y espacios en blanco; entonces, si pasa la salida a xargs, use la opción -print0 de find, así como la opción -0 de xargs, que le indica que use delimitadores nulos en la entrada. Otros comandos, incluido tar, también admiten la opción -0 y funcionan con entradas delimitadas por nulos, por lo que siempre debes usar esta opción para aquellos comandos que la admiten, a menos que estés 100% seguro de que la lista de entradas no te producirá problemas.

Nuestro último comentario se refiere a trabajar con una lista de archivos. Es una buena idea comprobar siempre cuidadosamente la lista y los comandos antes de realizar operaciones por lotes (como eliminar o cambiar el nombre de varios archivos). Tener una copia de seguridad actualizada cuando sea necesario también puede resultar invaluable.

División de salida

Para concluir este artículo, echaremos un vistazo rápido a un comando más. A veces es posible que necesites ver el resultado en la pantalla y guardarlo en un archivo al mismo tiempo. Para esto tu Pudimos redirigir la salida de un comando a un archivo en una ventana y luego usar tail -fn1 para rastrear la salida en otra ventana, pero la forma más sencilla es usar el comando tee.

El comando tee se usa en una canalización y su argumento es el nombre del archivo (o nombres de varios archivos) al que se canalizará la salida estándar. La opción -a le permite no reemplazar el contenido antiguo del archivo con contenido nuevo, sino agregar los datos al final del archivo. Como se analizó cuando analizamos la canalización, si desea almacenar tanto la salida estándar como el flujo de errores, debe redirigir stderr a stdout antes de pasar datos como entrada al comando tee. El Listado 21 muestra un ejemplo del uso del comando tee para guardar la salida en dos archivos, f1 y f2.

Listado 21. Dividiendo la salida estándar usando el comando tee
$ ls texto|tee f1 f2 texto1 texto2 texto3 $ gato f1 texto1 texto2 texto3 $ gato f2 texto1 texto2 texto3

Ya está familiarizado con dos métodos para trabajar con la salida de scripts de línea de comando:

  • Visualización de los datos de salida en la pantalla.
  • Redirigir la salida a un archivo.
A veces es necesario mostrar algo en la pantalla y escribir algo en un archivo, por lo que es necesario comprender cómo maneja Linux la entrada y la salida, lo que significa aprender a enviar los resultados de los scripts a donde los necesita. Comencemos hablando de descriptores de archivos estándar.

Descriptores de archivos estándar

Todo en Linux son archivos, incluidas la entrada y la salida. El sistema operativo identifica archivos mediante descriptores de archivos.

Cada proceso puede tener hasta nueve identificadores de archivos abiertos. El shell bash reserva los primeros tres identificadores con los ID 0, 1 y 2. Esto es lo que significan.

  • 0 , STDIN - flujo de entrada estándar.
  • 1, STDOUT: flujo de salida estándar.
  • 2, STDERR: flujo de error estándar.
Estos tres identificadores especiales manejan la entrada y salida del script.
Es necesario comprender realmente las transmisiones estándar. Se pueden comparar con la base sobre la que se construye la interacción de los guiones con el mundo exterior. Veamos los detalles sobre ellos.

ESTDIN

STDIN es el flujo de entrada estándar del shell. Para un terminal, la entrada estándar es el teclado. Cuando los scripts utilizan el carácter de redirección de entrada:< , Linux заменяет дескриптор файла стандартного ввода на тот, который указан в команде. Система читает файл и обрабатывает данные так, будто они введены с клавиатуры.

Muchos comandos bash aceptan entradas de STDIN a menos que la línea de comando especifique un archivo del cual tomar los datos. Por ejemplo, esto es cierto para el comando cat.

Cuando ingresa el comando cat en la línea de comando sin especificar ningún parámetro, acepta entradas de STDIN. Después de ingresar la siguiente línea, cat simplemente la muestra en la pantalla.

SALIDA ESTÁNDAR

STDOUT es el flujo de salida estándar del shell. Por defecto esta es la pantalla. La mayoría de los comandos bash envían datos a STDOUT, lo que hace que aparezcan en la consola. Los datos se pueden redirigir a un archivo agregándolos a su contenido usando el comando >>.

Entonces tenemos un archivo de datos al que podemos agregar más datos usando este comando:

Contraseña >> miarchivo
Las salidas de pwd se agregarán al archivo myfile, pero los datos que ya están en él no irán a ninguna parte.

Redirigir la salida del comando a un archivo

Hasta ahora todo bien, pero ¿qué pasa si intentas hacer algo como lo siguiente accediendo a un xfile inexistente, todo diseñado para provocar que se envíe un mensaje de error a myfile?

Ls –l xfile > miarchivo
Después de ejecutar este comando, veremos mensajes de error en la pantalla.


Intentando acceder a un archivo inexistente

Se genera un error al intentar acceder a un archivo inexistente, pero el shell no ha redirigido los mensajes de error al archivo imprimiéndolos en la pantalla. Pero queríamos que los mensajes de error entraran en el archivo. ¿Qué hacer? La respuesta es simple: utilice el tercer descriptor estándar.

ESTDERR

STDERR es el flujo de errores estándar del shell. De forma predeterminada, este identificador apunta a lo mismo que apunta STDOUT, razón por la cual vemos un mensaje en la pantalla cuando ocurre un error.

Entonces, digamos que queremos redirigir los mensajes de error a, por ejemplo, un archivo de registro o algún otro lugar, en lugar de imprimirlos en la pantalla.

▍Redireccionamiento del flujo de errores

Como ya sabes, el identificador del archivo STDERR es 2. Podemos redirigir errores colocando este identificador antes del comando de redirección:

Ls -l xfile 2>miarchivo cat ./miarchivo
El mensaje de error ahora irá a miarchivo.


Redirigir un mensaje de error a un archivo

▍Error de redirección y flujos de salida

Al escribir scripts de línea de comando, puede haber situaciones en las que necesite redirigir tanto los mensajes de error como la salida estándar. Para lograr esto, necesita usar comandos de redirección para los descriptores apropiados, especificando los archivos donde deben ir los errores y la salida estándar:

Ls –l miarchivo xarchivo otro archivo 2> contenido de error 1> contenido correcto

Errores de redireccionamiento y salida estándar

El shell redirigirá lo que el comando ls normalmente enviaría a STDOUT al archivo de contenido correcto gracias a la construcción 1>. Los mensajes de error que irían a STDERR terminan en el archivo de contenido de error debido al comando 2> de redirección.

Si es necesario, tanto STDERR como STDOUT se pueden redirigir al mismo archivo usando el comando &>:


Redirigiendo STDERR y STDOUT al mismo archivo

Después de ejecutar el comando, lo que está destinado a STDERR y STDOUT termina en el archivo de contenido.

Redirigir la salida en scripts

Hay dos métodos para redirigir la salida en scripts de línea de comando:
  • Redirección temporal o redirección de salida de una sola línea.
  • Redirección permanente, o redirección de todo o parte de la salida de un script.

▍Redirección de salida temporal

En un script, puedes redirigir la salida de una sola línea a STDERR. Para hacer esto, simplemente use el comando de redirección, especificando el descriptor STDERR y precediendo el número del descriptor con un carácter comercial (&):

#!/bin/bash echo "Esto es un error" >&2 echo "Esto es una salida normal"
Si ejecuta el script, ambas líneas aparecerán en la pantalla, ya que, como ya sabe, por defecto los errores se muestran en el mismo lugar que los datos normales.


Redirección temporal

Ejecutemos el script para que la salida STDERR vaya a un archivo.

./myscript 2> miarchivo
Como puede ver, ahora la salida normal se envía a la consola y los mensajes de error van a un archivo.


Los mensajes de error se escriben en un archivo.

▍Redirección de salida permanente

Si su secuencia de comandos necesita redirigir una gran cantidad de resultados a la pantalla, es inconveniente agregar el comando apropiado a cada llamada de eco. En su lugar, puede configurar la salida para que se redirija a un identificador específico durante la duración del script usando el comando exec:

#!/bin/bash exec 1>outfile echo "Esta es una prueba de redirección de todos los resultados" echo "desde un script de shell a otro archivo". echo "sin tener que redirigir cada línea"
Ejecutemos el script.


Redirigir toda la salida a un archivo

Si observa el archivo especificado en el comando de redirección de salida, encontrará que todo lo que generaron los comandos de eco terminó en ese archivo.

El comando exec se puede utilizar no sólo al principio del script, sino también en otros lugares:

#!/bin/bash exec 2>myerror echo "Este es el inicio del script" echo "ahora redirige todos los resultados a otra ubicación" exec 1>myfile echo "Esto debería ir al archivo myfile" echo "y esto debería ir al archivo myerror" >&2
Esto es lo que obtienes después de ejecutar el script y observar los archivos a los que redirigimos la salida.


Redirigir la salida a diferentes archivos

El comando exec primero redirige la salida de STDERR al archivo myerror. Luego, la salida de varios comandos de eco se envía a STDOUT y se imprime en la pantalla. Luego, el comando exec hace que todo lo que termine en STDOUT se envíe al archivo myfile y, finalmente, usamos el comando de redirección a STDERR en el comando echo, lo que hace que la línea correspondiente se escriba en el archivo myerror.

Una vez que domine esto, podrá redirigir la salida a donde desee que vaya. Ahora hablemos de la redirección de entrada.

Redirigir entradas en scripts

Para redirigir la entrada, puede utilizar la misma técnica que utilizamos para redirigir la salida. Por ejemplo, el comando exec le permite convertir un archivo en la fuente de datos para STDIN:

Ejecutivo 0< myfile
Este comando le dice al shell que la fuente de entrada debe ser myfile en lugar del STDIN normal. Veamos la redirección de entrada en acción:

#!/bin/bash ejecutivo 0< testfile count=1 while read line do echo "Line #$count: $line" count=$(($count + 1)) done
Esto es lo que aparecerá en la pantalla después de ejecutar el script.


Redirección de entrada

En un artículo anterior, aprendió a utilizar el comando de lectura para leer la entrada del usuario desde el teclado. Si redirige la entrada convirtiendo la fuente de datos en un archivo, entonces el comando de lectura, cuando intente leer datos de STDIN, los leerá desde el archivo y no desde el teclado.

Algunos administradores de Linux utilizan este enfoque para leer y luego procesar archivos de registro.

Creando tu propia redirección de salida

Al redirigir la entrada y la salida en scripts, no está limitado a los tres descriptores de archivos estándar. Como ya se mencionó, puedes tener hasta nueve manijas abiertas. Los seis restantes, numerados del 3 al 8, se pueden utilizar para redirigir la entrada o la salida. Cualquiera de ellos puede asignarse a un archivo y usarse en código script.

Puede asignar un identificador para generar datos usando el comando exec:

#!/bin/bash exec 3>myfile echo "Esto debería mostrarse en la pantalla" echo "y debería almacenarse en el archivo" >&3 echo "Y esto debería volver a aparecer en la pantalla"
Después de ejecutar el script, parte del resultado aparecerá en la pantalla y otra parte en un archivo con el descriptor 3.


Redirigir la salida usando su propio identificador

Crear descriptores de archivos para la entrada de datos

Puede redirigir la entrada en un script de la misma manera que redirige la salida. Guarde STDIN en otro identificador antes de redirigir la entrada.

Después de terminar de leer el archivo, puedes restaurar STDIN y usarlo como de costumbre:

#!/bin/bash ejecutivo 6<&0 exec 0< myfile count=1 while read line do echo "Line #$count: $line" count=$(($count + 1)) done exec 0<&6 read -p "Are you done now? " answer case $answer in y) echo "Goodbye";; n) echo "Sorry, this is the end.";; esac
Probemos el escenario.


Redirección de entrada

En este ejemplo, se utilizó el descriptor de archivo 6 para almacenar una referencia a STDIN. Luego se realizó la redirección de entrada y el archivo se convirtió en la fuente de datos para STDIN. La entrada al comando de lectura provino entonces del STDIN redirigido, es decir, del archivo.

Después de leer el archivo, restablecemos STDIN redirigiéndolo al controlador 6. Ahora, para comprobar que todo funciona correctamente, el script hace una pregunta al usuario, espera la entrada del teclado y procesa lo que se ingresa.

Cerrar identificadores de archivos

El shell cierra automáticamente los identificadores de archivos una vez que se completa el script. Sin embargo, en algunos casos es necesario cerrar los identificadores manualmente antes de que termine de ejecutarse el script. Para cerrar un identificador, se debe redirigir a &- . Se parece a esto:

#!/bin/bash exec 3> myfile echo "Esta es una línea de datos de prueba" >&3 exec 3>&- echo "Esto no funcionará" >&3
Después de ejecutar el script, recibiremos un mensaje de error.


Intentando acceder a un descriptor de archivo cerrado

El caso es que intentamos acceder a un descriptor que no existe.

Tenga cuidado al cerrar identificadores de archivos en scripts. Si envió datos a un archivo, luego cerró el identificador y luego lo abrió nuevamente, el shell reemplazará el archivo existente por uno nuevo. Es decir, se perderá todo lo escrito previamente en este archivo.

Obtener información sobre identificadores abiertos

Para obtener una lista de todos los identificadores abiertos en Linux, puede usar el comando lsof. En muchas distribuciones, como Fedora, la utilidad lsof se encuentra en /usr/sbin. Este comando es bastante útil porque muestra información sobre cada identificador que está abierto en el sistema. Esto incluye lo que abren los procesos que se ejecutan en segundo plano y lo que abren los usuarios que han iniciado sesión.

Este comando tiene muchas claves, veamos las más importantes.

  • -p Le permite especificar el ID del proceso.
  • -d Le permite especificar el número del descriptor sobre el que desea obtener información.
Para averiguar el PID del proceso actual, puede utilizar una variable de entorno especial $$, en la que el shell escribe el PID actual.

El modificador -a se utiliza para realizar una operación AND lógica en los resultados devueltos mediante el uso de los otros dos modificadores:

Lsof -a -p $$ -d 0,1,2

Mostrar información sobre identificadores abiertos

El tipo de archivos asociados con STDIN, STDOUT y STDERR es CHR (modo de caracteres). Como todos apuntan a un terminal, el nombre del archivo coincide con el nombre del dispositivo asignado al terminal. Los tres archivos estándar se pueden leer y escribir.

Veamos cómo llamar al comando lsof desde un script en el que, además de los estándar, están abiertos otros descriptores:

#!/bin/bash ejecutivo 3> miarchivo1 ejecutivo 6> miarchivo2 ejecutivo 7< myfile3 lsof -a -p $$ -d 0,1,2,3,6,7
Esto es lo que sucede si ejecuta este script.


Ver identificadores de archivos abiertos por un script

El script abrió dos controladores para salida (3 y 6) y uno para entrada (7). También se muestran las rutas a los archivos utilizados para configurar los descriptores.

Supresión de salida

A veces es necesario asegurarse de que los comandos de un script, que, por ejemplo, se pueden ejecutar como proceso en segundo plano, no muestren nada en la pantalla. Para hacer esto, puede redirigir la salida a /dev/null . Esto es algo así como un "agujero negro".

A continuación se muestra un ejemplo de cómo suprimir mensajes de error:

Ls -al archivo incorrecto otro archivo 2> /dev/null
Se utiliza el mismo enfoque si, por ejemplo, necesita borrar un archivo sin eliminarlo:

Cat /dev/null > miarchivo

Resultados

Hoy aprendiste cómo funcionan la entrada y la salida en los scripts de línea de comandos. Ahora sabe cómo manejar descriptores de archivos, crearlos, verlos y cerrarlos, y sabe cómo redirigir flujos de entrada, salida y errores. Todo esto es muy importante en el desarrollo de scripts bash.

La próxima vez hablaremos sobre las señales de Linux, cómo manejarlas en scripts, ejecutar trabajos programados y tareas en segundo plano.

¡Queridos lectores! Este material proporciona los conceptos básicos para trabajar con flujos de entrada, salida y errores. Estamos seguros de que entre vosotros hay profesionales que pueden contaros todo esto que sólo viene con la experiencia. Si es así, te cedemos la palabra.

Las capacidades de redirección integradas de Linux le brindan una amplia gama de herramientas simplificadas para todo tipo de tareas. La capacidad de gestionar varios flujos de E/S aumentará significativamente la productividad, tanto al desarrollar software complejo como al gestionar archivos mediante la línea de comandos.

Hilos de E/S

La entrada y salida en un entorno Linux se distribuye entre tres subprocesos:

  • Entrada estándar (entrada estándar, stdin, número de hilo 0)
  • Salida estándar (stdout, número 1)
  • Error estándar o flujo de diagnóstico (error estándar, stderr, número 2)

Cuando un usuario interactúa con un terminal, la entrada estándar se transmite a través del teclado del usuario. La salida estándar y el error estándar se muestran como texto en el terminal del usuario. Estas tres corrientes se denominan corrientes estándar.

Entrada estándar

El flujo de entrada estándar normalmente pasa datos del usuario al programa. Los programas que esperan una entrada estándar normalmente reciben entrada desde un dispositivo (como un teclado). La entrada estándar se detiene cuando llega a EOF (fin de archivo). EOF indica que no hay más datos para leer.

Para ver cómo funciona la entrada estándar, ejecute el programa cat. El nombre de esta herramienta significa “concatenar” (conectar o combinar algo). Normalmente, esta herramienta se utiliza para combinar el contenido de dos archivos. Cuando se ejecuta sin argumentos, cat abre un símbolo del sistema y acepta el contenido de la entrada estándar.

Ahora ingresa algunos números:

1
2
3
Ctrl-D

Al ingresar un número y presionar Enter, envía una entrada estándar al programa cat en ejecución, que acepta los datos. A su vez, el programa cat muestra la entrada recibida en la salida estándar.

El usuario puede configurar EOF presionando ctrl-d, lo que hará que el programa cat se detenga.

Salida estándar

La salida estándar registra los datos generados por el programa. Si la salida estándar no ha sido redirigida, enviará texto al terminal. Intente ejecutar el siguiente comando como ejemplo:

echo Enviado al terminal a través de salida estándar

El comando echo, sin opciones adicionales, muestra en la pantalla todos los argumentos que se le pasan en la línea de comando.

Ahora ejecuta echo sin ningún argumento:

El comando devolverá una cadena vacía.

Error estándar

Esta secuencia estándar registra los errores generados por un programa que falló. Al igual que la salida estándar, este flujo envía datos al terminal.

Veamos un ejemplo de una secuencia de error del comando ls. El comando ls muestra el contenido de los directorios.

Sin argumentos, este comando devuelve el contenido del directorio actual. Si proporciona un nombre de directorio como argumento para ls, el comando devolverá su contenido.

Como el directorio % no existe, el comando devolverá el error estándar:

ls: no se puede acceder %: no existe dicho archivo o directorio

Redirección de flujo

Linux proporciona comandos especiales para redirigir cada hilo. Estos comandos escriben la salida estándar en un archivo. Si la salida se redirige a un archivo inexistente, el comando creará un nuevo archivo con ese nombre y guardará la salida redirigida en él.

Los comandos con un corchete angular sobrescriben el contenido existente del archivo de destino:

  • > - salida estándar
  • < — стандартный ввод
  • 2> - error estándar

Los comandos con corchetes angulares dobles no sobrescriben el contenido del archivo de destino:

  • >> - salida estándar
  • << — стандартный ввод
  • 2>> - error estándar

Considere el siguiente ejemplo:

gato > escribir_a_mi.txt
a
b
C
Ctrl-D

Este ejemplo utiliza el comando cat para escribir la salida en un archivo.

Revise el contenido de write_to_me.txt:

gato write_to_me.txt

El comando debería devolver:

Redirige a cat a write_to_me.txt nuevamente e ingresa tres números.

gato > escribir_a_mi.txt
1
2
3
Ctrl-D

Ahora verifique el contenido del archivo.

gato write_to_me.txt

El comando debería devolver:

Como puede ver, el archivo solo contiene el resultado más reciente porque el comando que redirigió el resultado utilizó un corchete angular único.

Ahora intenta ejecutar el mismo comando con dos corchetes angulares:

gato >> escribir_a_mi.txt
a
b
C
Ctrl-D

Abra write_to_me.txt:

1
2
3
a
b
C

Los comandos con corchetes angulares dobles no sobrescriben el contenido existente, sino que lo agregan.

Transportadores

Las tuberías redirigen la salida de un comando a la entrada de otro. En este caso, los datos transferidos al segundo programa no se muestran en el terminal. Los datos aparecerán en la pantalla sólo después de ser procesados ​​por el segundo programa.

Las canalizaciones en Linux están representadas por una barra vertical.

Por ejemplo:

Este comando pasará la salida de ls (el contenido del directorio actual) a less, lo que mostrará los datos que se le pasaron línea por línea. Normalmente, ls muestra el contenido de los directorios de forma consecutiva, sin dividirlos en líneas. Si redirige la salida de ls a less, el último comando dividirá la salida en líneas.

Como puede ver, una canalización puede redirigir la salida de un comando a la entrada de otro, a diferencia de > y >>, que solo redirigen datos a archivos.

Filtros

Los filtros son comandos que pueden cambiar la redirección y la salida de una canalización.

Nota: Los filtros también son comandos estándar de Linux que se pueden usar sin una canalización.

  • buscar: busca un archivo por nombre.
  • grep: busca texto usando un patrón determinado.
  • tee: redirige la entrada estándar a la salida estándar y uno o más archivos.
  • tr: busca y reemplaza cadenas.
  • wc – contar caracteres, líneas y palabras.

Ejemplos de redirección de E/S

Ahora que está familiarizado con los conceptos y mecanismos básicos de la redirección, veamos algunos ejemplos básicos de su uso.

comando > archivo

Este patrón redirige la salida estándar del comando a un archivo.

ls ~> root_dir_contents.txt

Este comando pasa el contenido del directorio raíz del sistema como salida estándar y escribe la salida en el archivo root_dir_contents. Esto eliminará todo el contenido anterior del archivo, ya que el comando utiliza un corchete angular único.

comando > /dev/null

/dev/null es un archivo especial (llamado "dispositivo nulo") que se utiliza para suprimir la salida estándar o los diagnósticos para evitar salidas de consola no deseadas. Todos los datos que terminan en /dev/null se descartan. La redirección a /dev/null se usa comúnmente en scripts de shell.

ls > /dev/nulo

Este comando restablece la salida estándar devuelta por ls a /dev/null.

comando 2 > archivo

Este patrón redirige el flujo de error estándar del comando a un archivo, sobrescribiendo su contenido actual.

mkdir "" 2> mkdir_log.txt

Este comando redirigirá el error causado por un nombre de directorio no válido y lo escribirá en log.txt. Tenga en cuenta: el error todavía aparece en la terminal.

comando >> archivo

Este patrón redirige la salida estándar del comando a un archivo sin sobrescribir el contenido actual del archivo.

echo Escrito en un archivo nuevo > data.txt
echo Agregado al contenido de un archivo existente >> data.txt

Este par de comandos primero redirige la entrada del usuario a un archivo nuevo y luego lo pega en un archivo existente sin sobrescribir su contenido.

comando 2 >> archivo

Este patrón redirige el flujo de error estándar del comando a un archivo sin sobrescribir el contenido existente del archivo. Es adecuado para crear registros de errores de programas o servicios, ya que el contenido del registro no se actualizará constantemente.

busque "" 2> stderr_log.txt
baño "" 2>> stderr_log.txt

El comando anterior redirige el mensaje de error causado por el argumento de búsqueda no válido al archivo stderr_log.txt y luego agrega el mensaje de error causado por el argumento wc no válido al archivo stderr_log.txt.

equipo | equipo

Este patrón redirige la salida estándar del primer comando a la entrada estándar del segundo comando.

encontrar /var lib | grep deb

Este comando busca en el directorio /var y sus subdirectorios nombres de archivos y extensiones deb y devuelve las rutas de los archivos, resaltando el patrón de búsqueda en rojo.

equipo | archivo de camiseta

Este patrón redirige la salida estándar del comando a un archivo y sobrescribe su contenido, luego muestra la salida redirigida en la terminal. Si el archivo especificado no existe, crea un archivo nuevo.

En este patrón, el comando tee se usa normalmente para ver el resultado del programa y guardarlo en un archivo al mismo tiempo.

baño /etc/magia | camiseta magic_count.txt

Este comando pasa la cantidad de caracteres, líneas y palabras en el archivo mágico (Linux usa esto para determinar los tipos de archivos) al comando tee, que envía estos datos a la terminal y al archivo magic_count.txt.

equipo | equipo | comando >> archivo

Esta plantilla redirige la salida estándar del primer comando y la filtra a través de los dos comandos siguientes, luego agrega el resultado final a un archivo.

ls ~ | grep *alquitrán | tr e E >> ls_log.txt

Este comando envía la salida de ls para el directorio raíz a grep. A su vez, grep busca archivos tar en los datos recibidos. Después de esto, el resultado de grep se pasa al comando tr, que reemplazará todos los caracteres e con el carácter E. El resultado resultante se agregará al archivo ls_log.txt (si dicho archivo no existe, el comando creará automáticamente).

Conclusión

Las funciones de redirección de E/S de Linux parecen demasiado complejas al principio. Sin embargo, trabajar con la redirección es una de las habilidades más importantes de un administrador de sistemas.

Para obtener más información sobre un comando en particular, utilice:

comando hombre | menos

Por ejemplo:

Este comando devolverá una lista completa de comandos para tee.

Etiquetas:


Arriba