Polecenie find daje następujące dane wyjściowe:
[root @ localhost /] # find var / log / -iname anaconda. * var / log / anaconda.log var / log / anaconda.xlog var / log / anaconda.yum.log var / log / anaconda.syslog var / log / anaconda.program.log var / log / anaconda.storage.log
Po połączeniu ze smołą wyświetla następujące dane wyjściowe:
[root @ localhost /] # find var / log / -iname anaconda. * -exec tar -cvf file.tar {} \; var / log / anaconda.log var / log / anaconda.xlog var / log / anaconda.yum.log var / log / anaconda.syslog var / log / anaconda.program.log var / log / anaconda.storage.log
Ale podczas wyświetlania pliku tar wyświetla tylko jeden plik
[root @ localhost /] # tar -tvf plik.tar -rw ------- root / root 208454 27.02.2012 12:01 var / log / anaconda.storage.log
Co tutaj robię źle?
Z xargs otrzymuję ten wynik:
[root @ localhost /] # find var / log / -iname anaconda. * | xargs tar -cvf plik1.tar
Drugie Pytanie
Podczas pisania / przed var, oznacza to, find /var/log
dlaczego daje on ten komunikat tar: Usuwanie wiodącego `/ 'z nazw członków
[root @ localhost /] # find / var / log / -iname anaconda. * -exec tar -cvf file.tar {} \; tar: Usuwanie wiodącego `/ 'z nazw członków /var/log/anaconda.log tar: Usuwanie wiodącego `/ 'z nazw członków /var/log/anaconda.xlog tar: Usuwanie wiodącego `/ 'z nazw członków /var/log/anaconda.yum.log tar: Usuwanie wiodącego `/ 'z nazw członków /var/log/anaconda.syslog tar: Usuwanie wiodącego `/ 'z nazw członków /var/log/anaconda.program.log tar: Usuwanie wiodącego `/ 'z nazw członków /var/log/anaconda.storage.log
W prostej formie jaka jest różnica między następującymi dwoma?
find var/log
i find /var/log
find
poleceniem, powinieneś zacytować szukany termin. Działa czasami, ale nie zawsze.{} +
zamiast{} \;
tego zgrupuje wyniki find w jeden argumentOdpowiedzi:
Uwaga: Zobacz odpowiedź @ Iaina na bardziej wydajne rozwiązanie.
Pamiętaj, że
find
wywoła-exec
akcję dla każdego znalezionego pliku .Jeśli uruchamiasz
tar -cvf file.tar {}
dla każdego pojedynczego plikufind
wyjściowego, oznacza to, że zafile.tar
każdym razem nadpisujesz , co wyjaśnia, dlaczego kończysz się pozostawieniem jednego archiwum, które zawiera tylkoanaconda.storage.log
- są to ostatnie plikifind
wyjściowe.Teraz faktycznie chcesz dodawać pliki do archiwum zamiast tworzyć go za każdym razem (tak robi ta
-c
opcja). Więc skorzystaj z następujących opcji:-r
Opcja dołącza do archiwum zamiast odtwarzając go za każdym razem.Uwaga: Wymień
-iname anaconda.*
się-iname "anaconda.*"
. Gwiazdka jest symbolem wieloznacznym i może być rozszerzona przez powłokę, zanimfind
ją zobaczy. Aby temu zapobiec, zawiń argument w podwójne cudzysłowy.Jeśli chodzi o
tar
usuwanie wiodących/
: archiwum powinno zawierać tylko względne nazwy plików. Jeśli dodasz pliki ze znakiem wiodącym/
, zostaną one zapisane jako bezwzględne nazwy plików, dosłownie/var/…
na przykład na twoim komputerze.IIRC jest to po prostu środek ostrożności dla
tar
implementacji innych niż GNU, i jest bezpieczniejszy w ten sposób, ponieważ nie zastąpisz faktycznych danych/var/…
podczas rozpakowywania archiwum, jeśli zawiera względne nazwy plików.źródło
tar
ten sposób archiwizować taśmę, dodając jeden plik naraz, przewijając taśmę, a następnie ponownie czytając wszystko za każdym razem, aby dojść do końca, wszystko będzie absurdalnie wolne. Twoje rozwiązanie jest odpowiednie tylko wtedy, gdy zapisujesz plik tar na dysk.find /var/log/ -iname anaconda*
nic nie daje ifind /var/log/ -iname anaconda.*
daje wynik, dlaczego?find
. Więc jeśli takanaconda*
, a w bieżącym folderze jest coś o nazwie na przykładanaconda5
(pasujące do tego symbolu wieloznacznego), symbol wieloznaczny zostanie rozwinięty i zamiast niegofind
zobaczysz . Dlaczego pierwszy nie działa, a drugi działa, zależy od tego, jakie pliki znajdują się w bieżącym katalogu. @max-iname anaconda5
-iname anaconda*
{} +
zamiast,{} \;
aby zgrupować wyniki find w jednym argumencieMożesz użyć czegoś takiego jak:
-print0
I-T
współpracują ze sobą w celu umożliwienia nazwy plików ze spacjami nowej linii itp Ostateczna-
nakazuje tar odczytać nazwy plików wejściowych z stdin.Pamiętaj, że
-print0
zgodnie z tą odpowiedzią musi znajdować się na końcu Twojego oświadczenia . W przeciwnym razie prawdopodobnie otrzymasz więcej plików, niż się spodziewasz.źródło
-name
opcję, powodując rozwiązanie dlatar
całego katalogu. Jeśli tego właśnie chcesz, możesz to zrobić łatwiej niżtar -cvf file.tar var/log
bez użyciafind
.tar
to dobry pomysł. Jest to zdecydowanie najlepsze rozwiązanie, jeśli spodziewasz się, że nazwy ścieżek mogą zawierać spacje. Opisałbym to nawet jako najlepsze technicznie, ponieważ jest zarówno niezawodne, jak i wydajne. Ale wymaga to dodatkowej specjalnej wiedzy na temat obufind
itar
. Wolę podstawianie poleceń tylko dlatego, że jest to bardziej ogólne narzędzie: Naucz się go używać raz, a następnie używaj go wszędzie. (Ale przyznaję, jestem w systemie Windows z powłoką, w której zawsze działa.) Przepraszam, jeśli wydawałem się niegrzeczny.xargs
.-print0
opcji find , potrzebujesz również--null
opcji tar .--no-unquote
okazuje się być również potrzebny: nazwy plików zawierające ukośniki odwrotne byłyby w przeciwnym razie źle traktowane. (Nie, to nie jest hipotetyczne - naprawdę tworzę archiwum tar z kodu innej osoby, zawierające nazwę pliku z odwrotnymi ukośnikami w nazwie, tak się dowiedziałem.)Spróbuj tego:
Próbowałeś użyć
find
do-exec tar
. Ale sposób działania tej-exec
opcji powoduje, że uruchamia to polecenie raz dla każdego znalezionego pasującego pliku, co powodujetar
zastąpienie tworzonego pliku tar za każdym razem. Właśnie dlatego skończyłeś z ostatnim. Ponadto musisz umieścić cudzysłowy wokół określonego wzorca, abyfind
powłoka go nie rozwijała przed przekazaniem gofind
.Używając podstawiania komend za pomocą odwrotnych
$(...)
znaków (lub używając notacji, jeśli wolisz), cała lista utworzonych nazwfind
jest wklejana z powrotem do wiersza komend jako argumentytar
, powodując, że zapisują je wszystkie naraz.źródło
find
rzadko jest dobrym pomysłem. mywiki.wooledge.org/ParsingLsread -r
z-print0
) jak ja w mojej odpowiedzi.Pytanie 1
Twoje polecenie kończy się niepowodzeniem, ponieważ
tar
pobiera każdy ze znalezionych plików i archiwizuje jefile.tar
. Za każdym razem spowoduje to zastąpienie wcześniej utworzonegofile.tar
.Jeśli chcesz mieć jedno archiwum ze wszystkimi plikami, po prostu uruchom je
tar
bezpośrednio, nie ma potrzebyfind
(i tak, działa to w przypadku plików ze spacjami w nazwach):pytanie 2
Te dwa polecenia są zupełnie różne:
find var / log przeszuka katalog o nazwie,
var/log
który jest podkatalogiem twojego bieżącego katalogu , jest to równoważnefind ./var/log
(zauważ./
).znaleźć / var / log wyszuka katalog o nazwie
/var/log
, która jest podkatalogu root/
.Wiadomość wiodąca
/
pochodzi odtar
niefind
. Oznacza to, że usuwa pierwszą/
z twoich nazw plików, aby przekształcić ścieżki bezwzględne w względne . Oznacza to, że plik/var/log/anaconda.error
zostanie wyodrębniony do./var/log/anaconda.error
momentu rozpakowania archiwum.źródło
Istnieją dwa sposoby
-exec
działania. Jeden sposób uruchamia polecenie wiele razy - raz dla każdego pliku; w inny sposób uruchamia polecenie raz, włączając wszystkie pliki jako listę parametrów.-exec tar -cvf file.tar {} ';'
uruchamiatar
polecenie dla każdego pliku, zastępując archiwum za każdym razem.-exec tar -cvf file.tar {} '+'
uruchamiatar
polecenie raz, tworząc archiwum wszystkich znalezionych plików.źródło
Myślę, że użycie -exec dla każdego pliku może spowolnić kompresję tar, jeśli masz dużo plików. Wolę użyć polecenia:
źródło
/bin/cpio: xxx: Cannot open: Too many open files