El comando find da esta salida:
[root @ localhost /] # find var / log / -iname anaconda. * var / log / anaconda.log var / log / anaconda.xlog var / log / anaconda.yum.log var / log / anaconda.syslog var / log / anaconda.program.log var / log / anaconda.storage.log
Después de combinar con tar, muestra esta salida:
[root @ localhost /] # find var / log / -iname anaconda. * -exec tar -cvf file.tar {} \;
var / log / anaconda.log
var / log / anaconda.xlog
var / log / anaconda.yum.log
var / log / anaconda.syslog
var / log / anaconda.program.log
var / log / anaconda.storage.log
Pero al enumerar el archivo tar, solo muestra un único archivo
[root @ localhost /] # tar -tvf file.tar -rw ------- root / root 208454 2012-02-27 12:01 var / log / anaconda.storage.log
¿Qué estoy haciendo mal aquí?
Con xargs obtengo esta salida:
[root @ localhost /] # find var / log / -iname anaconda. * | xargs tar -cvf file1.tar
Segunda pregunta
Mientras escribe / delante de var, significa find /var/logpor qué le está dando este tar de mesaage : eliminando los principales '/' de los nombres de miembros
[root @ localhost /] # find / var / log / -iname anaconda. * -exec tar -cvf file.tar {} \;
tar: eliminando los principales '/' de los nombres de miembros
/var/log/anaconda.log
tar: eliminando los principales '/' de los nombres de miembros
/var/log/anaconda.xlog
tar: eliminando los principales '/' de los nombres de miembros
/var/log/anaconda.yum.log
tar: eliminando los principales '/' de los nombres de miembros
/var/log/anaconda.syslog
tar: eliminando los principales '/' de los nombres de miembros
/var/log/anaconda.program.log
tar: eliminando los principales '/' de los nombres de miembros
/var/log/anaconda.storage.log
En una forma simple, ¿cuál es la diferencia entre los dos siguientes?
find var/log y find /var/log

findcomando, debe citar el término de búsqueda. Funciona sin a veces pero no siempre.{} +lugar de{} \;eso, agrupará los resultados de find en un argumentoRespuestas:
Nota: Vea la respuesta de @ Iain para una solución algo más eficiente.
Tenga en cuenta que
findllamará a la-execacción para cada archivo que encuentre.Si ejecuta
tar -cvf file.tar {}para cadafindsalida de archivo individual , esto significa que sobrescribiráfile.tarcada vez, lo que explica por qué termina con un archivo restante que solo contieneanaconda.storage.log: son las últimasfindsalidas de archivo .Ahora, realmente desea agregar los archivos al archivo en lugar de crearlo cada vez (esto es lo que hace la
-copción). Entonces, use lo siguiente:La
-ropción se agrega al archivo en lugar de recrearlo cada vez.Nota: Reemplace
-iname anaconda.*con-iname "anaconda.*". El asterisco es un comodín y su caparazón puede expandirlofindincluso antes de verlo. Para evitar esta expansión, envuelva el argumento entre comillas dobles.En cuanto a
tareliminar el encabezado/: el archivo solo debe contener nombres de archivo relativos . Si agrega archivos con un encabezado/, se almacenarán como nombres de archivo absolutos , es decir, literalmente/var/…en su computadora, por ejemplo.IIRC esto es simplemente una precaución para
tarimplementaciones que no sean GNU, y es más seguro de esta manera porque no sobrescribirá sus datos reales/var/…cuando extraiga el archivo si contiene nombres de archivo relativos.fuente
tarhacer un archivo de cinta real de esta manera, agregando un archivo a la vez, rebobinando la cinta y volviendo a leer todo cada vez para llegar al final, todo sería ridículamente lento. Su solución solo es adecuada si está escribiendo el archivo tar en el disco.find /var/log/ -iname anaconda*dando nada yfind /var/log/ -iname anaconda.*dando la salida, ¿por qué?findmás. Entonces, si tieneanaconda*, y en su carpeta actual hay algo llamado, por ejemplo,anaconda5(que coincide con este comodín), el comodín se expandirá yfindverá en-iname anaconda5lugar de-iname anaconda*. El motivo por el cual el primero no funciona y el segundo sí depende de qué archivos estén en su directorio actual. @max{} +lugar de{} \;para agrupar los resultados de encontrar en un argumentoPuedes usar algo como:
El
-print0y-Ttrabajar juntos para permitir nombres de archivo con espacios de nueva línea, etc. El final-le dice a tar que lea los nombres de archivo de entrada desde stdin.Tenga en cuenta que
-print0debe aparecer al final de su declaración, según esta respuesta . De lo contrario, probablemente obtendrá más archivos de los que esperaba.fuente
-nameopción, causando su solución atartodo el directorio. Si eso es lo que quieres, puedes hacerlo más fácilmentetar -cvf file.tar var/logsin usarlofind.tares una buena idea. Definitivamente es la mejor solución si espera que los nombres de las rutas puedan tener espacios. Incluso lo describiría como el mejor técnicamente, ya que es confiable y eficiente. Pero requiere un conocimiento especial adicional de ambosfindytar. Prefiero la sustitución de comandos prácticamente solo porque es una herramienta más general: aprenda a usarla una vez, luego úsela en todas partes. (Pero lo reconozco, estoy en Windows con un shell donde siempre funciona). Disculpas si parecía grosero.xargs.-print0opción find , también necesita la--nullopción tar .--no-unquoteresulta que también es necesario: los nombres de archivo que contengan barras invertidas se manejarían de forma incorrecta. (No, esto no es hipotético: realmente estoy creando un archivo tar a partir del código de otra persona, que contiene un nombre de archivo con barras invertidas en el nombre, así es como lo descubrí.)Prueba esto:
Que estaba tratando de usar
finda-exec tar. Pero la forma en que funciona la-execopción, ejecuta ese comando una vez para cada archivo coincidente que encuentra, haciendotarque se sobrescriba el archivo tar que produce cada vez. Es por eso que solo terminaste con el último. Además, debe poner comillas alrededor del patrón que especifique parafindque el shell no lo expanda antes de pasarlofind.Usando la sustitución de comandos con backticks (o usando la
$(...)notación si lo prefiere), la lista completa de nombres producidos porfindse vuelve a pegar en la línea de comandos como argumentostar, lo que hace que los escriba todos a la vez.fuente
findrara vez es una buena idea. mywiki.wooledge.org/ParsingLsread -rde-print0) como hice en mi respuesta.Pregunta 1
Su comando falla porque
tarestá tomando cada uno de los archivos encontrados y archivándolosfile.tar. Cada vez que lo haga, sobrescribirá el creado anteriormentefile.tar.Si lo que desea es un archivo con todos los archivos, simplemente ejecútelo
tardirectamente, no es necesariofind(y sí, esto funciona para archivos con espacios en sus nombres):Pregunta 2
Los dos comandos son completamente diferentes:
find var / log buscará un directorio llamado
var/logque es un subdirectorio de su directorio actual , es equivalente afind ./var/log(observe el./).find / var / log buscará un directorio llamado
/var/logque es un subdirectorio de la raíz,/.El
/mensaje principal es detar, nofind. Significa que está eliminando el primero/de sus nombres de archivo para convertir las rutas absolutas en relativas . Esto significa que el archivo/var/log/anaconda.errorse extraerá./var/log/anaconda.errorcuando desempaquete el archivo.fuente
Hay dos formas de
-exectrabajar. Una forma ejecuta el comando muchas veces, una vez para cada archivo; la otra forma ejecuta el comando una vez, incluidos todos los archivos como una lista de parámetros.-exec tar -cvf file.tar {} ';'ejecuta eltarcomando para cada archivo, sobrescribiendo el archivo cada vez.-exec tar -cvf file.tar {} '+'ejecuta eltarcomando una vez, creando un archivo de todos los archivos encontrados.fuente
Creo que usar -exec para cada archivo puede hacer que la compresión de tar sea muy lenta, si tienes muchos archivos. Prefiero usar el comando:
fuente
/bin/cpio: xxx: Cannot open: Too many open files