¿Cómo es legal este comando? "> Archivo1 <archivo2 gato"

61

Suponiendo que file2ya existe, el comando

> file1 < file2 cat

parece estar copiando el contenido de file2a file1.

Pero no puedo entender esta estructura.

Entiendo que "Nada" se dirige a file1(crear o borrar su contenido). Entonces file2se dirige el contenido de file1.

¿Por qué es catdespués file2? ¿Cómo sabe cat file2si los operandos no están en el orden correcto?

shaqed
fuente
11
¿Qué "orden correcto"? ¿Puede proporcionar un enlace a algún recurso / material de aprendizaje donde se describe un "orden correcto"?
Lightness compite con Monica el
77
Al hacer preguntas como esta, debe especificar el shell; diferentes tienen diferentes casos de borde, especialmente alrededor de la redirección.
chrylis -on strike-

Respuestas:

117

Antes de que el shell ejecute el catcomando en la línea de comando, busca redirecciones.

Hay dos redirecciones:

  1. >file1 Esto hará que la salida estándar del comando vaya a file1.
  2. <file2 Esto hará que la entrada estándar del comando provenga file2.

El hecho de que estas redirecciones se coloquen en una ubicación inestable en la línea de comando no importa.

$ cat <file2 >file1

es lo mismo que

$ <file2 cat >file1

que es lo mismo que

$ <file2 >file1 cat

etc.¹

Tenga en cuenta que la catutilidad en todas estas instancias se ejecuta sin ningún argumento de línea de comandos . Las redirecciones no son operandos al catcomando, son instrucciones al shell para configurar las redirecciones dentro y fuera del comando (conectando su entrada y salida estándar a los archivos). El shell configura las redirecciones antes de invocar el comando.

La diferencia entre el cat filey el cat <file(o, si se quiere, <file cat) es que en el primer caso, la catutilidad en sí está abriendo el archivo, que se da como un operando en la línea de comandos, para la lectura, mientras que en el segundo caso, la cáscara se abra el archivo y conecte catla secuencia de entrada de él². En el segundo caso, catnotará que no se le dio un operando de archivo y cambiará automáticamente a lectura desde su entrada estándar. Esta es una característica de cat, y de algunas otras utilidades, no algo que hacen todas las utilidades.

cattambién leerá desde su entrada estándar si se le da el operando -. Nuevamente, esto es especial solo para catalgunas otras utilidades (es decir, nada que haga el shell ). Para usar caten un archivo en el directorio actual cuyo nombre es - , agregue una ruta al nombre del archivo, como ./-.

¹ El orden de las redirecciones sigue siendo importante en algunas circunstancias; Con cat <file2 >file1, por ejemplo, file1no se truncará si file2es inaccesible (las redirecciones se analizan de izquierda a derecha). catSin embargo, la ubicación relativa de la palabra sigue siendo arbitraria y no influirá en esto.

² Consulte también la pregunta " cat da un error diferente al abrir un archivo no existente ".


El hecho de que el shell configure las redirecciones incluso antes de ejecutar el comando en la línea de comando es la razón por la cual fallan cosas como estas y terminas con un archivo de salida vacío:

$ sort file >file

Aquí, el shell truncará (vaciará) el archivo fileantes de ejecutar sort filey conectar sortla salida estándar del archivo. La sortutilidad se abrirá filey ordenará su contenido (que no es nada). El resultado (nada) se pasa a través de la secuencia de salida estándar a file.

El remedio en este caso particular (para ordenar un archivo "en el lugar") es

$ sort -o file file

o

$ sort file >file.sorted && mv file.sorted file

que es más o menos lo que sorthace cuando se usa el -oarchivo para especificar el nombre del archivo de salida.


Solo para respaldar la afirmación de que las redirecciones pueden preceder al nombre real de la utilidad en la línea de comando:

Un "comando simple" es una secuencia de asignaciones y redirecciones de variables opcionales, en cualquier secuencia, opcionalmente seguida de palabras y redirecciones, terminadas por un operador de control. [ref: POSIX Shell Command Language 2.9.1 Comandos simples]

Y también sobre la redirección que no forma parte de los operandos de la utilidad:

El número opcional, el operador de redireccionamiento y la palabra no aparecerán en los argumentos proporcionados al comando que se ejecutará (si corresponde). [ref: redirección POSIX Shell Command Language 2.7]

Kusalananda
fuente
14
@Steve La libertad de mover las redirecciones puede usarse para aclarar algunos comandos, como una tubería con redirección de entrada al principio que <in foo | bar >outpone todo en orden lógico. También me gusta la echo >&2 Something bad happenedsalida de errores de los scripts de shell. Pero >out <in cates solo ofuscación
2
¿Cómo podría sort file >filelograrse correctamente?
seth10
11
@setht con sort -o file file.
Kusalananda
66
Gran respuesta. Tenga en cuenta que el orden es importante. < file1 > file2 catsería mejor que > file2 < file1 cateso evitaría file2ser truncado si file1no se puede abrir.
Stéphane Chazelas
3
Algo a tener en cuenta: cuando se vincula a POSIX con fragmentos HTML, es mejor especificar la edición exacta (como pubs.opengroup.org/onlinepubs/9699919799.2016edition ) ya que se sabe que los fragmentos cambian entre las ediciones de una misma revisión de la especificación (muchos enlaces en las respuestas en este sitio, incluido el mío, ahora están equivocados ya que los fragmentos apuntan en el lugar equivocado después de que se lanzó la edición 2016).
Stéphane Chazelas