Cómo hacer que el bloqueo de alquitrán funcione con la opción 'cambiar directorio'


8

Tengo la siguiente estructura de directorios:

base/
   files/
   archives/
   scripts/

Quiero ejecutar un script scripts/, comprimir archivos que coincidan results.*.logen files/un archivo tar comprimido con gzip archives/.

Estoy intentando el siguiente comando:

tar czfC ../archives/archive.tar.gz ../files results.*.log

Pero consigo

tar: results.*.log: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

Mientras

tar czfC ../archives/archive.tar.gz ../files results.a.log

Funciona como se esperaba. también

tar czf ../archives/archive.tar.gz ../files/results.*.log

funciona de la manera que me gustaría, excepto que agrega el prefijo files/al archivo y también emite una advertencia:

tar: Removing leading `../' from member names

Entonces, mi conclusión es que el tarbloqueo no funciona correctamente cuando se usa la -Copción. ¿Algún consejo sobre cómo hago que esto funcione de una manera simple?

Respuestas:


3

Escríbalo de la manera más portátil:

(cd ../files && tar cf - results.*.log) | 
  gzip -9 > ../archives/archive.tar.gz

El glob aún se interpretará en el directorio actual, antes de que cdsuceda.
vonbrand

1
@vonbrand, no, por supuesto que no. &&es como ;o nueva línea, separa dos comandos. Es como decir que después de ejecutarse cd, cualquier glob expandiría los archivos en el directorio anterior.
Stéphane Chazelas

Tienes razón. Uno nunca termina de aprender.
vonbrand

5

No hay "globulación de alquitrán", el glocking lo realiza el caparazón. Y el shell no tiene idea de que tar -C somedirhará su trabajo somedir, cualquier globo se expande en el directorio actual.


De hecho, si results.a.logexiste en el directorio desde el que se ejecuta el script, funciona. Pero no entiendo por qué sucede esto, ya que -Csignifica cambio de directorio, por lo que el directorio actual debería ser el que tiene results.a.log. No puedo aceptar tu respuesta porque no ofreces una solución.
Yuval

2
El shell toma el comando, expande los globos en el directorio actual, fabrica los argumentos de lo anterior y lanza el tarprograma, que cambia el directorio mucho más tarde. No puedo "resolver" tu problema, lo siento. La única forma de salir es moverse al directorio donde desea glob, o hacer el globbing en el directorio y guardar sus resultados en un archivo o variable.
vonbrand

1

Puede dejar de pasar por findalto y omitir la opción 'cambiar directorio' tareliminando el files/prefijo antes de crear el archivo tar.

La --no-recursionopción a tares opcional ya que no se archivarán directorios.

cd base/scripts

# gnutar
# printf '%s\000' ../files/results.*.log |  # find alternative
find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | 
   gnutar --transform="s|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | 
   gzip -9 > ../archives/archive.tar.gz
gnutar -tf ../archives/archive.tar.gz | nl
gnutar -xzf ../archives/archive.tar.gz

# bsdtar
find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | 
   bsdtar -s "|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | 
   gzip -9 > ../archives/archive.tar.gz
bsdtar -tf ../archives/archive.tar.gz | nl
bsdtar -xzf ../archives/archive.tar.gz

0

Finalmente usé

tar czfC ../archives/archive.tar.gz ../files `find ../files/results.*.log -printf "%f\n"`

Si bien eso puede funcionar para usted, es una forma bastante compleja de hacerlo. Además, no funcionará con nombres de archivo que contengan caracteres especiales como espacios en blanco. Utilice uno de los métodos sanos que se han propuesto en las respuestas.
Gilles 'SO- deja de ser malvado'

0

La forma de hacerlo es escribir algo como lo siguiente:

#!/bin/sh

cd ../files
tar zcf ../archives/archive.tar.gz results.*.log
cd ../scripts

0

No es el alquitrán el que pega, es el caparazón. Primero le está diciendo al shell que haga globbing, luego le dice a tar que cambie los directorios. Como tar está recibiendo una lista de nombres de archivos relativos a los directorios originales, esto no funciona.

La solución más fácil con diferencia es dejar que el shell cambie el directorio. Interactivamente:

cd ../files
tar czf ../archives/archive.tar.gz  results.*.log
cd -

En un guion:

(
  cd ../files &&
    tar czf ../archives/archive.tar.gz  results.*.log
)

o

(
  cd ../files &&
    tar czf -  results.*.log
) >../archives/archive.tar.gz
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.