¿Es un UUOC (uso inútil del gato) para networkingirigir un file a otro?

Si quiero que el contenido del file2 coincida con el contenido del file1 , obviamente podría ejecutar cp file1 file2 .

Sin embargo, si deseo conservar todo lo relacionado con el file2 excepto el propietario del contenido, los permissions, los attributes extendidos, las ACL, los enlaces duros, etc., entonces no me gustaría ejecutar cp . * En ese caso, solo quiero despliega el contenido de file1 en file2 .

Parece que lo siguiente lo haría:

 < file1 > file2 

Pero no funciona. file2 se trunca a nada y no se escribe en. Sin embargo,

 cat < file1 > file2 

funciona

Me sorprendió que la primera versión no funciona.

¿La segunda versión es UUOC? ¿Hay alguna manera de hacer esto sin invocar un command, simplemente mediante el uso de networkingirecciones?

Nota: soy consciente de que UUOC es más un punto pedante que un verdadero antipatrón.

* Como se descubrió en tniles09 , cp de hecho funcionará en este caso.

cat < file1 > file2 no es un UUOC. Clásicamente, < y > hacen networkingirecciones que corresponden a las duplicaciones del descriptor de files a nivel del sistema. Las duplicaciones del descriptor de files por sí mismas no hacen nada (bueno, > networkingirecciones se abren con O_TRUNC , por lo que para ser exactos, las networkingirecciones de salida truncan el file de salida). No dejes que los símbolos < > te confundan. Los redirects no mueven datos; asignan descriptores de files a otros descriptores de files.

En este caso, abra el file1 y asigne ese descriptor de file al descriptor de file 0 ( <file1 == 0<file1 ) y file2 y asigne ese descriptor de file al descriptor de file 1 ( >file2 == 1>file2 ).

Ahora que tiene dos descriptores de files, necesita un process para extraer datos entre los dos, y para eso es el cat .

No lo es, porque, como han señalado otros, el comportamiento en cuestión depende del armazón. Como usted (OP) ha señalado, esto es un poco pedante , tal vez incluso humorístico. , tipo de tema.

Sin embargo, en los sistemas GNU, su premisa inicial tiene otra solución disponible: cp --no-preserve=all file1 file2 . Pruébelo, creo que satisfará su situación descrita (por ejemplo, modificando el contenido del file2 sin modificar sus attributes).

Ejemplo :

 $ ls -l total 8 -rw-r--r-- 1 tniles sambashare 16 Dec 16 12:21 fezzik -rw-r--r-- 1 tniles tniles 14 Dec 16 12:16 fnetworking $ cat * Lookout, world! Hello, world! $ cp --no-preserve=all fnetworking fezzik $ ls -l total 8 -rw-r--r-- 1 tniles sambashare 14 Dec 16 12:22 fezzik -rw-r--r-- 1 tniles tniles 14 Dec 16 12:16 fnetworking $ cat * Hello, world! Hello, world! 

ACTUALIZACIÓN En realidad, me di count de que el cp mi sistema por sí solo parece conservar los attributes a less que se especifique -a o -p . Estoy usando bash shell y GNU coreutils. Supongo que aprendes algo nuevo todos los días …


Resultados de la testing (por comodín) incluido el enlace físico y diferentes permissions:

 $ ls -li total 12 913966 -rw-rw-r-- 1 vagrant vagrant 30 Dec 16 20:26 file1 913965 -rwxrw---- 2 pete vagrant 39 Dec 16 20:35 file2 913965 -rwxrw---- 2 pete vagrant 39 Dec 16 20:35 hardlinktofile2 $ cat file1 This is the contents of file1 $ cat file2 This is the original contents of file2 $ cp file1 file2 $ ls -li total 12 913966 -rw-rw-r-- 1 vagrant vagrant 30 Dec 16 20:26 file1 913965 -rwxrw---- 2 pete vagrant 30 Dec 16 20:37 file2 913965 -rwxrw---- 2 pete vagrant 30 Dec 16 20:37 hardlinktofile2 $ cat file1 This is the contents of file1 $ cat file2 This is the contents of file1 $ 

En zsh , el shell donde < file1 > file2 funciona, el shell invoca a cat .

Para una command-line que consta solo de networkingirecciones y ningún command ni asignaciones, zsh invoca $NULLCMD ( cat por defecto) a less que la única networkingirección sea un < en cuyo caso se $READNULLCMD ( pager por defecto) en su lugar. (eso a less que zsh esté en emulación sh o csh en cuyo caso se comporta como las conchas que emula).

Asi que:

 < file1 > file2 

es en realidad lo mismo que

 cat < file1 > file2 

y

 < file1 

es lo mismo que

 pager < file1 
 < from > to 

no funciona porque no hay ningún command allí; sin process El shell abre / crea los files y organiza las networkingirecciones (lo que significa que los descriptores de files que hacen reference a estos files se plantan como 0 y 1: input estándar y salida estándar). Pero no hay nada que hacer ejecutando un ciclo para leer desde la input estándar y escribir en la salida estándar.

zsh hace que esto funcione al sustituir un command configurable por el usuario en este caso de "command nulo". El command no está visible en la línea de command, pero todavía está allí. Se crea un process para él y funciona de la misma manera. NULLCMD es cat por defecto, por lo que < from > to realidad significa cat < from > to en zsh , a less que NULLCMD esté establecido en otra cosa; es un command de "gato implícito".

Se produce un "uso inútil de cat" cuando se usa cat como intermediario para leer un file y alimentar los datos a otro process, cuyo descriptor de file podría simplemente conectarse al file original.

Si el cat es extraíble de la situación, de modo que los commands restantes aún pueden realizar la misma tarea, es inútil. Si no es extraíble, entonces no es inútil.

 # useless, removable: $ cat archive.tar | tar tf - # --> tar tf archive.tar # not removable (in POSIX shell): $ cat > file abc [Ctrl-D] # likewise: STRING=$(cat file) 

Un cat que es reemplazable no es lo mismo. Por ejemplo, en lugar de cat > file podemos usar el vi file para crear el file. Eso no count como eliminación de cat , mientras utiliza lo que queda para lograr la misma tarea.

Si cat es el único command en la tubería, entonces por supuesto no se puede eliminar; ninguna reorganización de lo que quede hará el trabajo equivalente.

Algunos scripters de shell usan cat porque creen que les permite mover el operando de input más cerca del lado izquierdo de la línea de command. Sin embargo, las networkingirecciones pueden estar en cualquier lugar de la línea de command:

 # If you're so inclined: # move source archive operand to the left without cat: $ < archive.tar tar xf - > listing 

< file1 > file2 Parece ser dependiente del shell, en zsh funciona, en bash no.

editar: statement falsa eliminada

Además de todas las buenas respuestas, puedes evitar un UUOC simulando un cat :

 awk 1 file1 > file2 # For line-oriented text, not binaries. dd if=file1 of=file2 # Works for binary files, too. # many more geeky ways. 

Estos commands no copyn los metadatos del file, como lo haría un cp simple.

Si funciona, no lo arregles.

yo usaría

 cat < file1 > file2 

y no te preocupes por la PC de la semántica.