Taruj katalog, ale nie przechowuj pełnych ścieżek bezwzględnych w archiwum

277

Mam następujące polecenie w części skryptu powłoki kopii zapasowej:

tar -cjf site1.bz2 /var/www/site1/

Kiedy wymieniam zawartość archiwum, otrzymuję:

tar -tf site1.bz2
var/www/site1/style.css
var/www/site1/index.html
var/www/site1/page2.html
var/www/site1/page3.html
var/www/site1/images/img1.png
var/www/site1/images/img2.png
var/www/site1/subdir/index.html

Chciałbym jednak usunąć część /var/www/site1z katalogu i nazw plików w archiwum, aby uprościć ekstrakcję i uniknąć niepotrzebnej stałej struktury katalogów. Nigdy nie wiem, na wypadek, gdybym wyodrębnił kopie zapasowe witryn w miejscu, w którym nie były przechowywane dane internetowe /var/www.

W powyższym przykładzie chciałbym mieć:

tar -tf site1.bz2
style.css
index.html
page2.html
page3.html
images/img1.png
images/img2.png
subdir/index.html

Tak więc, gdy rozpakowuję, pliki są wyodrębniane w bieżącym katalogu i nie muszę później przenosić wyodrębnionych plików, aby zachować struktury podkatalogów.

Jest już wiele pytań o tar i kopie zapasowe w stackoverflowinnych miejscach w sieci, ale większość z nich prosi o usunięcie całej struktury podkatalogu (spłaszczanie), lub po prostu dodanie lub usunięcie początkowego / w nazwach (nie t wiem, co się dokładnie zmienia podczas wypakowywania), ale nie więcej.

Po przeczytaniu niektórych rozwiązań tu i ówdzie, a także instrukcji, wypróbowałem:

tar -cjf site1.bz2 -C . /var/www/site1/
tar -cjf site1.bz2 -C / /var/www/site1/
tar -cjf site1.bz2 -C /var/www/site1/ /var/www/site1/
tar -cjf site1.bz2 --strip-components=3 /var/www/site1/

Ale żaden z nich nie działał tak, jak chcę. Niektórzy nic nie robią, inni nie archiwizują już podkatalogów.

Znajduje się w skrypcie powłoki kopii zapasowej uruchomionym przez Crona, więc nie wiem dobrze, który użytkownik go uruchamia, jaka jest ścieżka i katalog bieżący, więc zawsze wszystko wymaga wpisania ścieżki bezwzględnej i wolałbym nie zmieniać bieżącego katalogu aby uniknąć zepsucia czegoś w skrypcie (ponieważ nie tylko tworzy kopie zapasowe stron internetowych, ale także baz danych, a następnie przesyła to wszystko na FTP itp.)

Jak to osiągnąć?

Czy właśnie źle zrozumiałem, jak działa opcja -C?

QuentinC
źródło
powiązane: unix.stackexchange.com/questions/22842/tar-with-relative-paths | serverfault.com/questions/339762
Ciro Santilli 9 冠状 病 六四 事件 法轮功
Cóż, -Coznacza po prostu „zmień katalog”, a zastąpienie ścieżki (lub prefiksu) może być wykonane tylko przez --transform. rif. superuser.com/questions/595510/prepend-prefix-in-tar/595512 możesz w prosty sposób -C (zmienić katalog) i --transformować go: `` tar cjf site1.bz2 --transform "s / ^ \. \ // $ targetbase / "-C / var / www / site1. ``
Daniele Cruciani
To bardzo dobre pytanie i niestety żadna z odpowiedzi na tę datę nie jest zadowalająca. Jeszcze nie wiemy od jakiejś mądrej osoby, jak moglibyśmy wyodrębnić pojedynczy plik style.css (przykład powyżej) do bieżącego katalogu bez odniesienia do oryginalnej lokalizacji lub drzewa katalogów? Nie chcę zaśmiecać mojego bieżącego katalogu niechcianą nową strukturą drzewa. Brzmi jak poważna wada tarballa, która jest ignorowana przez lata.
elmclose

Odpowiedzi:

383
tar -cjf site1.tar.bz2 -C /var/www/site1 .

W powyższym przykładzie tar zmieni katalog na /var/www/site1przed wykonaniem swojej czynności, ponieważ -C /var/www/site1podano opcję .

Od man tar:

OTHER OPTIONS

  -C, --directory DIR
       change to directory DIR
Lars Brinkhoff
źródło
152
Nie przegap kropki na końcu, to ważne ;-)
Freedom_Ben
9
co powiesz, jeśli chcesz również wybrać pliki do kopii zapasowej na podstawie znaku wieloznacznego? -C / var / www / site1 * .dat nie działa :(
Andy Lorenz
16
Kropka informuje taro zarchiwizowaniu wszystkiego w bieżącym katalogu. I -Custawia bieżący katalog.
Lars Brinkhoff
21
To działa świetnie. Uważam, że warto zachować nazwę katalogu (po prostu nie pełną ścieżkę), więc wykonałem następujące czynności: tar -czvf site1.tar.gz -C /var/www/ site1(Zwróć uwagę na spację, nadal używam -C, aby cd do katalogu macierzystego i określając katalog do tar zamiast kropki)
jorfus,
9
Dostaję wiodącą kropkę na ścieżce smoły, np. ./foldersJak można to usunąć?
Mika571,
39

Opcja -Cdziała; tylko dla wyjaśnienia opublikuję 2 przykłady:

  1. stworzenie tarballa bez pełnej ścieżki: pełna ścieżka /home/testuser/workspace/project/application.wari to, czego chcemy, to po prostu project/application.war:

    tar -cvf output_filename.tar  -C /home/testuser/workspace project

    Uwaga: pomiędzy workspacei jest spacja project; tar zastąpi pełną ścieżkę just project.

  2. ekstrakcja tarballa ze zmianą ścieżki docelowej (domyślnie na .np. bieżący katalog)

    tar -xvf output_filename.tar -C /home/deploy/

    tarwyodrębni tarball na podstawie podanej ścieżki i zachowa ścieżkę tworzenia; w naszym przykładzie plik application.warzostanie rozpakowany /home/deploy/project/application.war.

    /home/deploy: podany przy wyciągu
    project: podany przy tworzeniu tarballa

Uwaga: jeśli chcesz umieścić utworzony plik tarball w katalogu docelowym, po prostu dodaj ścieżkę docelową przed nazwą pliku tarball. na przykład:

tar -cvf /path/to/place/output_filename.tar  -C /home/testuser/workspace project
Grizli
źródło
1
jak dodać symbol wieloznaczny do wyboru pliku w ostatnim przykładzie?
Siva
Problem z symbolami wieloznacznymi polega na tym, że powłoka rozszerza je do pasujących nazw plików i tar nie rozszerza ich, jeśli są cytowane ...
Gert van den Berg
Próbowałem tego na Ubuntu 18.04 i bez powodzenia. Nie jestem pewien, czego mi brakuje. Mój stdout wyświetla go poprawnie po spakowaniu, ale kiedy go rozpakowuję, nadal ma pełną ścieżkę
sdc
14

Wydaje się, że -Copcja upto tar v2.8.3 nie działa konsekwentnie na wszystkich platformach (systemach operacyjnych). -Copcja mówi się, aby dodać katalog do archiwum, ale na Macu i Ubuntu dodaje absolutny prefiks ścieżki do wygenerowanego pliku tar.gz.

tar target_path/file.tar.gz -C source_path/source_dir

Dlatego spójnym i niezawodnym rozwiązaniem jest przejście cddo ścieżki_źródłowej (katalog macierzysty katalogu_źródłowego) i uruchomienie

tar target_path/file.tar.gz source_dir

lub

tar -cf target_path/file.tar.gz source_dir

w twoim skrypcie. Spowoduje to usunięcie prefiksu ścieżki bezwzględnej w strukturze katalogów wygenerowanego pliku tar.gz.

Chinthaka Senanayaka
źródło
1
Użycie opcji -C DID usunęło prefiksy absolutnych ścieżek w wygenerowanym pliku tar.gz na fedora 29. Czy twoja odpowiedź jest specyficzna dla jakiegoś systemu?
EL_DON
@EL_DON: Nie testowałem opcji -C na Fedorze, ale idealnie oprogramowanie tar powinno działać konsekwentnie na każdej platformie, chyba że jest to błąd w aplikacji tar. -C opcja, testowałem na Mac 10.8 i Mac 10.13 oraz Ubuntu (wersja, której nie pamiętam). Ale od tar v2.8.3 komenda została zmieniona na tar -cf ścieżka_docelowa / plik.tar.gz katalog_źródłowy i nadal, jeśli dodasz opcję -C, nie usunie przedrostka bezwzględnej ścieżki w wygenerowanym pliku tar.gz.
Chinthaka Senanayaka
Testowałem ponownie na systemie centOS. Po utworzeniu wszystkich ścieżek w przykładzie i uruchomieniu polecenia (z -cvfdodanym później tar) okazuje się, że wynikowy plik tar.gz nie zawiera ścieżek bezwzględnych, co jest zgodne z kilkoma innymi odpowiedziami. Jeśli uważasz, że tar jest uszkodzony lub nieaktualny w obu systemach, których użyłem do testowania, proszę link do dokumentacji, która potwierdziłaby twoją odpowiedź. Myślę, że -Copcja zmienia katalog przed wykonaniem (jak w innych odpowiedziach). Kiedy go pomijam, tar próbuje dodać śmieci ./, w tym ścieżki od początku ./.
EL_DON
Użyłem tego dokumentu: linux.die.net/man/1/tar Tak, dokument mówi -C zmieni ścieżkę, ale na moim Macu 10.13 to nie działa. może to być niespójne zachowanie aplikacji tar. To znaczy, że to błąd. Jeśli piszesz skrypt powłoki do uruchomienia na wszystkich platformach uniksowych, lepiej bądź bezpieczny dzięki działającemu kodowi, który będzie działał na wszystkich systemach operacyjnych.
Chinthaka Senanayaka
Twoja odpowiedź nie mówi, że może wystąpić błąd, a bardziej niezawodne rozwiązanie dla zgodności między platformami to cdpierwsze. Twoja odpowiedź mówi, że narzędzie działa w sposób odwrotny do tego, jak mówią doktorzy, że działa i jak działa w moim systemie, więc jest to zła odpowiedź. Możesz to łatwo naprawić.
EL_DON
7

Następujące polecenie utworzy katalog główny „.” i umieść w nim wszystkie pliki z określonego katalogu.

tar -cjf site1.tar.bz2 -C /var/www/site1 .

Jeśli chcesz umieścić wszystkie pliki w katalogu głównym pliku tar, @chinthaka ma rację. Po prostu włóż płytę do katalogu i wykonaj:

tar -cjf target_path/file.tar.gz *

Spowoduje to umieszczenie wszystkich plików w cwd w pliku tar jako plików root.

WLatif
źródło
1
Użycie * nie powoduje zapisania żadnych „ukrytych” plików .folderów. (fyi, użycie -C razem z * kończy się niepowodzeniem, powłoka rozszerza bieżący
katalog
1

Użycie „punktu” prowadzi do utworzenia folderu o nazwie „punkt” (w Ubuntu 16).

tar -tf site1.bz2 -C /var/www/site1/ .

Zajmowałem się tym bardziej szczegółowo i przygotowałem przykład. Nagrywanie wielu linii plus wyjątek.

tar -tf site1.bz2\
    -C /var/www/site1/ style.css\
    -C /var/www/site1/ index.html\
    -C /var/www/site1/ page2.html\
    -C /var/www/site1/ page3.html\
    --exclude=images/*.zip\
    -C /var/www/site1/ images/
    -C /var/www/site1/ subdir/
/
Sergey Asachev
źródło
Dlaczego nazywacie to „punktem”? To tylko .bieżący katalog. W kontekście tar.gzstruktury to tylko podstawowy / główny / najwyższy poziom, prawda?
EL_DON
Zobacz migawkę, aby zobaczyć szczegóły obrazu . Moja droga jest bardziej poprawna w użyciu, to moja opinia.
Sergey Asachev
0

Jeśli chcesz zarchiwizować podkatalog i przyciąć ścieżkę podkatalogu, to polecenie będzie przydatne:

tar -cjf site1.bz2 -C /var/www/ site1
Hirurg103
źródło