Jak spakować katalog, a następnie usunąć oryginały, w tym katalog?


30

Próbuję tarznaleźć kolekcję plików w katalogu o nazwie „mój_katalog” i usunąć oryginały za pomocą polecenia:

tar -cvf files.tar my_directory --remove-files

Jednak usuwa tylko pojedyncze pliki w katalogu, a nie sam katalog (co określiłem w poleceniu). Czego tu brakuje?

EDYTOWAĆ:

Tak, przypuszczam, że opcja „usuń pliki” jest dość dosłowna. Chociaż ja też uważałem, że strona podręcznika jest niejasna w tym punkcie. (W Linuksie raczej nie rozróżniam zbytnio katalogów i plików i czasami zapominam, że to nie to samo). Wygląda na to, że konsensus polega na tym, że nie usuwa katalogów.

Jednak mój główny powód, by zadać to pytanie, wynika z obchodzenia się ze ścieżkami bezwzględnymi. Ponieważ musisz określić ścieżkę względną do pliku / plików, który ma zostać skompresowany, musisz zatem przejść do katalogu nadrzędnego, aby odpowiednio go spakować. Moim zdaniem użycie jakiejkolwiek komendy „rm” jest potencjalnie niebezpieczne w tej sytuacji. Tak więc miałem nadzieję uprościć rzeczy, zmuszając tar do usunięcia.

Na przykład wyobraź sobie skrypt kopii zapasowej, w którym katalog kopii zapasowej (tj. Tar) jest zawarty jako zmienna powłoki. Jeśli ta wartość zmiennej powłoki została źle wprowadzona, możliwe, że wynik może zostać usunięty z dowolnego katalogu, w którym byłeś ostatnio.


Nicholas, twój punkt widzenia, że ​​stwarza niebezpieczeństwo, że trzeba usunąć drzewo katalogów w dodatkowym kroku, jest absolutnie słuszny. Myślę, że archiwizator powinien to zrobić bezpiecznie. Wierzę też, że taki był zamysł twórców GNU tar, przynajmniej tak powinno być ;-)
— mit

2
Przekonałem się, że opcja --remove-files rzeczywiście usuwa zawierający katalog - przynajmniej na niektórych platformach / w niektórych wersjach - i w moim przypadku. Być może w twoim przypadku pozostały katalog nie był całkowicie pusty z powodu modyfikacji niektórych plików po tarowaniu.
— isync

@ isync Wydaje mi się, że --remove-files kasuje katalogi na Ubuntu 14.04. Z wyjątkiem mojego przypadku nie chcę tego. Haha
— Bradley Odell,

Odpowiedzi:


12

Brakuje części, która mówi, że --remove-filesopcja usuwa pliki po dodaniu ich do archiwum.

Możesz wykonać operację archiwizacji i usuwania plików za pomocą polecenia, takiego jak:

znajdź / path / to / be / archived / -depth -type d -empty -exec rmdir {} \;


Aktualizacja: Być może zainteresuje Cię krótka dyskusja na temat Debiana,
Bug 424692: --remove-files narzeka, że ​​katalogi „zmieniły się w miarę, jak je czytamy” .


Może tak naprawdę: -czmienia katalog przed tarrozpoczęciem pracy (i jakby nie wraca, dopóki nie zostanie zrobiony)? Wydaje mi się, że usunęłoby to podkatalogi, gdyby były zawarte w archiwum (ale tego nie przetestowałem).
— Arjan

@Arajan, nie sądzę, żeby „ c'miało to coś wspólnego; 'remove-files'celowo nie usuwa katalogów.
— nik

Aha, krótkie wyjaśnienie „usuń pliki po dodaniu ich do archiwum” ze manstron nie jest zbyt jasne, ale zakładam, że masz rację. Mimo to nie spodziewałbym się, że wspomniany katalog -czostanie usunięty, nawet jeśli tar usuną również katalogi. (Dla mnie byłoby to jak usunięcie bieżącego katalogu, a więc także samego archiwum, gdy nie korzystam z -c...?) Ale jeśli -remove-fileszawsze pozostawia katalogi na swoim miejscu, to z pewnością komplikuję tutaj. ;-)
— Arjan

3
--remove-filesbłąd został naprawiony w tar-1.19.
— x-yuri

19

Ponieważ --remove-filesopcja usuwa tylko pliki , możesz spróbować

tar -cvf files.tar my_directory && rm -R my_directory

tak, że katalog jest usuwany tylko wtedy, gdy tarzwraca status wyjścia 0


9
z wyjątkiem tego, że powinieneś sprawdzić status wyjścia tar przed zrobieniem rm! w przeciwnym razie możesz zostać bez archiwum tar i plików ...
— Kim

1
Korzystając z katalogów jednego poziomu, uważam, że bezpieczniejszą opcją byłoby użycie „rmdir” zamiast „rm”, ponieważ usuwałby tylko pusty katalog. [Zobacz edycje pytań]
— Nicholas

Ale rmdirusuwa tylko puste katalogi. Pomysł polegał na usunięciu katalogu i zawartych w nim plików (pod warunkiem tarpowodzenia)
— pavium

--remove-filesbłąd został naprawiony w tar-1.19.
— x-yuri

&& uruchomi następującą komendę, tylko jeśli poprzednia komenda zakończyła działanie 0 (sukces). Jeśli wyjdzie> 0, następujące polecenie nie zostanie uruchomione. Możesz to również odwrócić za pomocą || - uruchom tylko, jeśli pierwsze polecenie nie powiodło się. Dobry sposób na wykonanie okropnej kontroli - ponownie ją uruchamia.
— Kirrus

6

Czy próbowałeś umieścić dyrektywę --remove-files po nazwie archiwum? Mi to pasuje.

tar -cvf files.tar --remove-files my_directory

1
Bardziej prawdopodobne jest, że zachowanie tar zmieniło się od czasu postawienia tego pytania. Dla mnie nie ma różnicy we wstawianiu --remove-filesprzed lub po my_directory; w obu przypadkach katalog jest usuwany.
— redburn

5
--remove-filesbłąd został naprawiony w tar-1.19.
— x-yuri

1
source={directory argument}

na przykład

source={FULL ABSOLUTE PATH}/my_directory

 

parent={parent directory of argument}

na przykład

parent={ABSOLUTE PATH of 'my_directory'/

 

logFile={path to a run log that captures status messages}

Następnie możesz wykonać coś w stylu:

cd ${parent}

tar cvf Tar_File.`date%Y%M%D_%H%M%S` ${source}

if [ $? != 0 ]

then

 echo "Backup FAILED for ${source} at `date` >> ${logFile}

else

 echo "Backup SUCCESS for ${source} at `date` >> ${logFile}

 rm -rf ${source}

fi

1

To był prawdopodobnie błąd.

Również słowo „plik” jest w tym przypadku niejednoznaczne. Ale ponieważ jest to przełącznik wiersza poleceń, spodziewałbym się, że będzie to oznaczać także katalogi, ponieważ w unix / lnux wszystko jest plikiem, także katalogiem. (Druga interpretacja jest oczywiście również aktualna, ale nie ma sensu utrzymywanie katalogów w takim przypadku. Uważałbym to za zachowanie nieoczekiwane i mylące).

Ale odkryłem, że w niektórych wersjach gnu tar gnu tar usuwa drzewo katalogów. Kolejnym sygnałem, że trzymanie drzewa było błędem. A przynajmniej jakieś obejście, dopóki go nie naprawią.

Oto, co wypróbowałem na konsoli Ubuntu 10.04:

mit: / var / tmp $ mkdir tree1                                                                                               
mit: / var / tmp $ mkdir tree1 / sub1                                                                                          
mit: / var / tmp $> tree1 / sub1 / file1                                                                                        

mit: / var / tmp $ ls -la                                                                                                    
drwxrwxrwt 4 root root 4096 14.11.2011 15:40.                                                                              
drwxr-xr-x 16 root root 4096 2011-02-25 03:15 ..
drwxr-xr-x 3 mit mit 4096 14.11.2011 15:40 drzewo1

mit: / var / tmp $ tar -czf tree1.tar.gz tree1 / --remove-files

# JAK MOŻESZ ZOBACZYĆ, ŻE DRZEWO ZOSTAŁO TERAZ:

mit: / var / tmp $ ls -la
drwxrwxrwt 3 root root 4096 14.11.2011 15:41.
drwxr-xr-x 16 root root 4096 2011-02-25 03:15 ..
-rw-r - r-- 1 mit mit 159 2011-11-14 15:41 tree1.tar.gz                                                                   


mit: / var / tmp $ tar --version                                                                                             
tar (GNU tar) 1.22                                                                                                           
Copyright © 2009 Free Software Foundation, Inc.

Jeśli chcesz zobaczyć to na swoim komputerze, wklej to do konsoli na własne ryzyko:

tar --version                                                                                             
cd / var / tmp
mkdir -p drzewo1 / sub1                                                                                          
> drzewo1 / sub1 / plik1                                                                                        
tar -czf drzewo1.tar.gz drzewo1 / --remove-files
ls -la
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.