So funktioniert Tar Globbing mit der Option "Verzeichnis ändern"

8

Ich habe die folgende Verzeichnisstruktur:

base/
   files/
   archives/
   scripts/

Ich möchte ein Skript aus ausführen scripts/, Dateien komprimieren , dass Spiel results.*.login files/in ein gzip - tar - Archiv in archives/.

Ich versuche den folgenden Befehl:

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

Aber ich verstehe

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

Während

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

funktioniert wie erwartet. Ebenfalls

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

funktioniert so, wie ich es möchte, außer dass es das Präfix files/zur Datei hinzufügt und auch eine Warnung ausgibt:

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

Mein Fazit ist also, dass tarGlobbing bei Verwendung der -COption nicht richtig funktioniert . Irgendwelche Ratschläge, wie ich diese Arbeit auf einfache Weise mache?

Yuval
quelle

Antworten:

3

Schreiben Sie es auf tragbarere Weise:

(cd ../files && tar cf - results.*.log) | 
  gzip -9 > ../archives/archive.tar.gz
Stéphane Chazelas
quelle
Der Glob wird weiterhin im aktuellen Verzeichnis interpretiert, bevor cddies geschieht.
vonbrand
1
@vonbrand, nein, natürlich nicht. &&ist wie ;oder newline, es trennt zwei Befehle. Es ist so, als würde man sagen, dass cdjeder Glob nach dem Ausführen Dateien im vorherigen Verzeichnis erweitern würde.
Stéphane Chazelas
Du hast recht. Man hört nie auf zu lernen.
vonbrand
5

Es gibt kein "Teer-Globbing", das Globbing erfolgt durch die Schale. Und die Shell hat keine Ahnung, tar -C somedirin somedirwelcher Funktion sie arbeiten wird. Alle Globs werden im aktuellen Verzeichnis erweitert.

vonbrand
quelle
Wenn results.a.loges in dem Verzeichnis vorhanden ist, in dem das Skript ausgeführt wird, funktioniert es tatsächlich . Aber ich verstehe nicht, warum dies passiert, da es -Cfür change directory steht, also sollte das aktuelle Verzeichnis dasjenige mit sein results.a.log. Ich kann Ihre Antwort nicht akzeptieren, weil Sie keine Lösung anbieten.
Yuval
2
Die Shell übernimmt den Befehl, erweitert Globs im aktuellen Verzeichnis, stellt die obigen Argumente her und startet das tarProgramm, das das Verzeichnis viel später ändert. Ich kann Ihr Problem leider nicht "lösen". Der einzige Ausweg besteht darin, in das Verzeichnis zu wechseln, in das Sie globalisieren möchten, oder das Globbing im Verzeichnis durchzuführen und die Ergebnisse in einer Datei oder Variablen zu speichern.
vonbrand
1

Sie können das Globbing ausführen findund die Option "Verzeichnis ändern" weglassen, tarindem Sie das files/Präfix entfernen, bevor Sie die Tarfile erstellen.

Die --no-recursionOption to tarist optional, da keine Verzeichnisse archiviert werden.

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
quelle
0

Ich habe es endlich benutzt

tar czfC ../archives/archive.tar.gz ../files `find ../files/results.*.log -printf "%f\n"`
Yuval
quelle
Das mag zwar für Sie funktionieren, ist aber eine ziemlich komplexe Methode. Darüber hinaus funktioniert es nicht mit Dateinamen, die Sonderzeichen wie Leerzeichen enthalten. Verwenden Sie eine der in den Antworten vorgeschlagenen vernünftigen Methoden.
Gilles 'SO - hör auf böse zu sein'
0

Der Weg, dies zu tun, besteht darin, etwas wie das Folgende zu schreiben:

#!/bin/sh

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

Es ist nicht Teer, der das Globbing macht, es ist die Schale. Sie fordern die Shell zuerst auf, Globbing durchzuführen, und dann Tar, das Verzeichnis zu wechseln. Da tar eine Liste von Dateinamen relativ zu den ursprünglichen Verzeichnissen erhält, funktioniert dies nicht.

Die mit Abstand einfachste Lösung besteht darin, die Shell das Verzeichnis ändern zu lassen. Interaktiv:

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

In einem Skript:

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

oder

(
  cd ../files &&
    tar czf -  results.*.log
) >../archives/archive.tar.gz
Gilles 'SO - hör auf böse zu sein'
quelle