Si quiero hacer que el contenido file2
coincida con el contenido de file1
, obviamente podría simplemente ejecutarlo cp file1 file2
.
Sin embargo, si quiero conservar todo alrededor file2
, excepto el contenido-propietario, permisos, atributos extendidos, ACL, enlaces duros, etc., etc., entonces yo no desee ejecutar cp
. * En ese caso, sólo quiero el plop contenido de file1
into 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
hace el trabajo.
Me sorprendió que la primera versión no funcione.
¿Es la segunda versión un UUOC? ¿Hay alguna manera de hacer esto sin invocar un comando, simplemente usando redirecciones?
Nota: Soy consciente de que UUOC es más un punto pedante que un verdadero antipatrón.
* Como tniles09 descubrió , cp
voluntad en el trabajo hecho en este caso.
fuente
< file1 > file2
hace lo que quiere depende de la shell.<
...file1
no existe o si no es legible y lo abre<
antes de>
que se abra la salida, y luego considere lo que sucede cuando permitecat
intentar abrirlo.cat
(por defecto), esencialmente ejecuta el segundo comando. Vea la respuesta de Stéphane Chazelas a continuación para obtener más información sobre eso que lo que cabe en un comentario.Respuestas:
cat < file1 > file2
No es un UUOC. Clásicamente,<
y>
realice redirecciones que correspondan a duplicaciones de descriptores de archivo a nivel del sistema. Las duplicaciones del descriptor de archivo por sí mismas no hacen nada (bueno, las>
redirecciones se abren conO_TRUNC
, por lo que, para ser precisos, las redirecciones de salida truncan el archivo de salida). No dejes que los<
>
símbolos te confundan. Las redirecciones no mueven datos: asignan descriptores de archivo a otros descriptores de archivo.En este caso, abre
file1
y asigna ese descriptor de archivo al descriptor de archivo0
(<file1
==0<file1
)file2
y asigna ese descriptor de archivo al descriptor de archivo1
(>file2
==1>file2
).Ahora que tiene dos descriptores de archivo, necesita un proceso para intercambiar datos entre los dos, y para eso
cat
está.fuente
No lo es, porque como otros han señalado, el comportamiento en cuestión depende de la concha. Como usted (el 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
. Pruebe esto, creo que satisfará su situación descrita (por ejemplo, modificando contenidosfile2
sin modificar sus atributos).Ejemplo :
ACTUALIZACIÓN En realidad, sólo se dio cuenta de que mi sistema
cp
por sí mismo parece conservar atributos a menos-a
o-p
están especificados. Estoy usando bash shell y GNU coreutils. Supongo que aprendes algo nuevo todos los días ...Resultados de la prueba (por comodín) incluyendo enlace duro y diferentes permisos:
fuente
En
zsh
el shell donde< file1 > file2
funciona, el shell invocacat
.Para una línea de comando que consiste solo en redirecciones y sin comando ni asignaciones,
zsh
invoca$NULLCMD
(cat
por defecto) a menos que la única redirección sea una<
en cuyo caso$READNULLCMD
(pager
por defecto) se invoca en su lugar. (eso es a menos quezsh
esté ensh
ocsh
emulación en cuyo caso se comporta como los shells que emula).Asi que:
en realidad es lo mismo que
y
es lo mismo que
fuente
no funciona porque no hay comando allí; sin proceso El shell abre / crea los archivos y organiza las redirecciones (lo que significa que los descriptores de archivo que hacen referencia a estos archivos se plantan como 0 y 1: entrada estándar y salida estándar). Pero no hay nada que hacer, ejecutar un ciclo para leer desde la entrada estándar y escribir en la salida estándar.
zsh
hace que esto funcione al sustituir un comando configurable por el usuario en este caso de "comando nulo". El comando no está visible en la línea de comando, pero todavía está allí. Se crea un proceso para él y funciona de la misma manera.NULLCMD
escat
por defecto, por lo que en< from > to
realidad significacat < from > to
adentrozsh
, a menos queNULLCMD
esté configurado en otra cosa; es un comando "gato implícito".Un "uso inútil de cat" ocurre cuando
cat
se usa como intermediario para leer de un archivo y alimentar los datos a otro proceso, cuyo descriptor de archivo podría estar conectado al archivo original.Si
cat
se puede eliminar de la situación, de modo que los comandos restantes aún pueden realizar la misma tarea, no sirve de nada. Si no es extraíble, entonces no es inútil.Un
cat
que es reemplazable no es lo mismo. Por ejemplo, en lugar decat > file
podemos usarvi file
para crear el archivo. Eso no cuenta como eliminación decat
, mientras se usa lo que queda para lograr la misma tarea.Si
cat
es el único comando 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 piensan que les permite mover el operando de entrada más cerca del lado izquierdo de la línea de comando. Sin embargo, las redirecciones pueden estar en cualquier lugar de la línea de comando:fuente
f -
para alquitrán.tar xf -
es justotar x
.cat
está involucrado en la creación del archivo? La respuesta dice claramente que el shell hace esto. ¿A qué problema> file
te refieres? A menudo lo uso solo para truncar un archivo existente a longitud cero o asegurar que exista. Esta pregunta es sobre por qué< from > to
no funciona asícat < from > to
, y UUoC, no "por favor, dame razones por lascat
que no es un buen sustituto decp
".tar
es el archivador de cinta . Muchastar
implementaciones aún funcionan con el primer dispositivo de cinta por defecto.< file1 > file2
Parece ser dependiente de shell, en zsh funciona, en bash no.editar: declaración falsa eliminada
fuente
cp -a
conserva los atributos del archivo1 y sobrescribe los atributos del archivo2. Frente al comportamiento deseado. Además no puedo decir incluso mirando a la página del manual de lo que sucederá con los enlaces duros, pero creo que es seguro decir que fichero2 se 's enlaces duros no ser preservados.Además de todas las buenas respuestas, puede evitar un UUOC simulando un
cat
:Estos comandos no copian los metadatos del archivo, como lo
cp
haría sin formato .fuente
cat
. Aquí necesita un comando para insertar datos entre los dos descriptores de archivo ycat
es uno de los mejores para eso. Vea tambiénpv
cuál podría usarsplice()
en Linux durante quince años (aunque no funcionafadvise(POSIX_FADV_SEQUENTIAL)
como locat
hace GNU ).dd
comando para archivos binarios parece bueno ... ¿ocat
funcionaría igual de bien para archivos binarios?cat
también funciona para archivos binarios (Unix generalmente no distingue; sin embargo, algunas herramientas funcionan específicamente línea por línea, como awk, grep, wc, ... POSIX también define una longitud mínima de línea más grande, por lo que en teoría una herramienta orientada a líneas podría negarse a tratar con líneas excesivamente grandes.)sed '' < file1 > file2
;-)Si funciona, no lo arregles.
yo usaría
y no sudar la PC de la semántica.
fuente