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?

Yuval
fuente

Respuestas:

3

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

(cd ../files && tar cf - results.*.log) | 
  gzip -9 > ../archives/archive.tar.gz
Stéphane Chazelas
fuente
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.

vonbrand
fuente
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
phron
fuente
0

Finalmente usé

tar czfC ../archives/archive.tar.gz ../files `find ../files/results.*.log -printf "%f\n"`
Yuval
fuente
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
vonbrand
fuente
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
Gilles 'SO- deja de ser malvado'
fuente