Estaba trabajando en un tutorial y vi el uso de ambos cat myfile.txt
y cat < myfile.txt
. ¿Hay alguna diferencia entre estas dos secuencias de comandos? Parece que ambos imprimen el contenido de un archivo en el shell.
Estaba trabajando en un tutorial y vi el uso de ambos cat myfile.txt
y cat < myfile.txt
. ¿Hay alguna diferencia entre estas dos secuencias de comandos? Parece que ambos imprimen el contenido de un archivo en el shell.
Respuestas:
En el primer caso, cat
abre el archivo, y en el segundo caso, el shell abre el archivo y lo pasa como cat
entrada estándar.
Técnicamente, podrían tener diferentes efectos. Por ejemplo, sería posible tener una implementación de shell que tuviera más (o menos) privilegios que el cat
programa. Para ese escenario, uno podría no abrir el archivo, mientras que el otro podría.
Ese no es el escenario habitual, pero mencionó señalar que el shell y cat
no son el mismo programa.
sudo cat myfile.txt
. Pero sudo cat < myfile.txt
no funcionará si no tiene privilegios para leer el archivo.
ksh93
tiene cat
incorporado (no está habilitado de forma predeterminada a menos que lo haya hecho /opt/ast/bin
temprano en su $PATH
aunque).
wc
imprimirá el nombre del archivo antes de los recuentos cuando se le dé un argumento.
No hay una diferencia visible importante en su caso de prueba. El más obvio sería el mensaje de error que aparece si no hay un nombre myfile.txt
en el directorio actual o si no se le permite leerlo.
En el primer caso, cat
se quejará y en el último caso, su shell lo hará, mostrando claramente qué proceso está intentando abrir el archivo, cat
en el primero y el shell en el último.
$ cat myfile.txt
cat: myfile.txt: No such file or directory
$ cat < myfile.txt
ksh93: myfile.txt: cannot open [No such file or directory]
En un caso más general, una diferencia importante es que el uso de redireccionamientos no se puede usar para imprimir el contenido de más de un archivo, que es, después de todo, el propósito original del comando cat
(es decir, cat enate). Tenga en cuenta que el shell de todos modos intentará abrir todos los archivos pasados como entrada redirigida, pero solo pasará el último a cat
menos que use zsh
y su multios
"zshism".
$ echo one > one
$ echo two > two
$ cat one two # cat opens one, shows one, opens two, shows two
one
two
$ cat < one < two # sh opens one then opens two, cat shows stdin (two)
two
$ rm one two
$ echo one > one
$ cat one two # cat opens and shows one, fails to open two
one
cat: two: No such file or directory
$ cat < one < two # the shell opens one then opens two, fails and
# displays an error message, cat gets nothing on stdin
# so shows nothing
ksh93: two: cannot open [No such file or directory]
En un sistema estándar, el shell y cat
no tienen diferencias en los derechos de acceso a archivos, por lo que ambos tendrán éxito o fallarán por igual. El uso sudo
para aumentar cat
los privilegios hará una gran diferencia en el comportamiento, como Thomas Dickey respondió y los comentarios adjuntos ya sugirieron.
ksh
tu propia voluntad, y si es así ... por qué ?
bash
, ksh93
es de lejos el mejor caparazón. Es la concha, casi.
cat < file1 > file2
tiene un efecto muy diferente cat file1 > file2
al del caso en que file1
es ilegible o inexistente. (La última forma se trunca file2
; la primera no.)
cat myfile.txt
lee el archivo y myfile.txt
luego lo imprime en la salida estándar.
cat < myfile.txt
aquí cat
no se le da ningún archivo para abrir, así que, como muchos comandos de Unix, lee los datos de la entrada estándar, que es dirigida desde file.txt
el shell, e imprime en la salida estándar.
La respuesta de @Thomas Dickey es brillante.
Solo quiero agregar algunos hechos obvios sobre el caso de leer varios archivos (relacionados con su pregunta, pero aún así):
cat <file1 <file2 <file3
leerá solo el archivo3, al menos en bash. (En realidad, depende del shell, pero la mayoría de los shells duplicarán cada archivo especificado en stdin, lo que hace que el último tenga efecto).cat file1 file2 file3
leerá todos los archivos especificados secuencialmente (en realidad, cat es la forma abreviada de la palabra concatenar ).cat file1 file2 file3 <file4 <file5 <file6
leerá solo archivo1, archivo2, archivo3 (ya que cat ignora la entrada estándar cuando se pasan los argumentos del nombre de archivo).
cat file1 file2 - file3 <file4 <file5 <file6
leerá file1, file2, file6, file3 (ya que el guión obliga a cat a no ignorar stdin).Y sobre los errores. En caso de no poder abrir algunos de los archivos especificados como argumentos (sin <
), cat omitirá los archivos fallidos (con la salida del mensaje relevante a stderr), pero aún leerá otros archivos. En caso de que no se pueda abrir al menos uno de los archivos especificados como redireccionamientos (con <
), el shell ni siquiera iniciará cat (esto ocurre incluso para redireccionamientos realmente no utilizados por cat). En ambos casos, se devolverá un código de salida erróneo.
cat
será, sin embargo, abrir file1
y file2
, con la misma file4
y file5
en su tercer ejemplo. Solo se mostrará file3
, resp. file6
contenido si estas instrucciones abiertas anteriores tienen éxito.
podemos usar otro comando para notar la diferencia entre:
wc –w food2.txt
.
Salida posible:
6 food2.txt
.
el comando le dice el nombre del archivo ya que lo sabe (pasado como argumento).
wc –w < food2.txt
.
Salida posible:
6
.
la entrada estándar se redirige al archivo food2.txt sin que el comando lo sepa.