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.

Mikołaj
źródło
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” .

nik
źródło
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

pavium
źródło
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
Robert Grubba
źródło
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
łuskanie
źródło
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
mit
źródło