Zastosowanie dołączania nawiasów klamrowych {} jako argumentów poleceń i ich opcji


11

Przykłady

Niedawno znalazłem przykłady użycia par otaczających nawiasów klamrowych {}, bez niczego między otwierającymi i zamykającymi nawiasami klamrowymi, jako argumentów dla poleceń, a nawet ich opcji:

cat foo | xargs -I{} echo {}

find . -size 0 -exec rm -i {} \;

Brak dokumentacji

Mój problem polega na tym, że nie mogę znaleźć dokumentacji w Podręczniku GNU Bash, która opisuje użycie {}w takim kontekście, jak w powyższych przykładach.

Nie sądzę, że jest to rozszerzenie parametru , ponieważ znak dolara musi poprzedzać otaczające nawiasy klamrowe w rozszerzeniu parametru jak w ${}.

Nie może to być również nawias klamrowy , ponieważ przyjmuje postać {x..y[..incr]}, gdzie xi ynie jest opcjonalny.

Nie może to być również grupa komend , ponieważ {}jest używana jako argument.

pytania

  1. Co para obejmujących nawiasów klamrowych w {}ogóle oznacza jako argument dla każdego polecenia, które je akceptuje?

  2. Gdzie mogę znaleźć dokumentację opisującą użycie {}argumentów?


Niektóre polecenia mają tę opcję {}- co oznacza, targetsże działając na findpolecenie, usuwają / rmodnajdują pliki.
Tuyen Pham

Odpowiedzi:


16

Te nawiasy klamrowe są pozostawione same przez uderzenie; należą one do findi xargs, odpowiednio, i są opisane w ich roboczo stronach.

man find

-exec Komenda ;

Wykonaj polecenie ; true, jeśli zwracany jest status 0. Wszystkie następujące argumenty do znalezienia są uważane za argumenty polecenia, dopóki nie zostanie znaleziony argument składający się z ;. Ciąg {}jest zastępowany bieżącą nazwą pliku przetwarzaną wszędzie tam, gdzie występuje w argumentach polecenia, a nie tylko w argumentach, w których jest on sam, jak w niektórych wersjach find. Obie te konstrukcje mogą wymagać ucieczki (za pomocą a \) lub cytowania, aby uchronić je przed rozszerzeniem przez powłokę. Przykłady użycia tej -execopcji znajdują się w sekcji PRZYKŁADY . Podane poleceniejest uruchamiany raz dla każdego dopasowanego pliku. Polecenie jest wykonywane w katalogu startowym. Istnieją nieuniknione problemy bezpieczeństwa związane z korzystaniem z -exec akcji; -execdirzamiast tego powinieneś użyć tej opcji.

-exec Komenda {} +

Ten wariant -execakcji uruchamia określone polecenie na wybranych plikach, ale linia poleceń jest budowana przez dołączenie każdej wybranej nazwy pliku na końcu; całkowita liczba wywołań polecenia będzie znacznie mniejsza niż liczba dopasowanych plików. Wiersz poleceń jest budowany w taki sam sposób, jak xargswiersze poleceń. {}W poleceniu dozwolona jest tylko jedna instancja Polecenie jest wykonywane w katalogu startowym. Jeśli findwystąpi błąd, może to czasami spowodować natychmiastowe wyjście, więc niektóre oczekujące polecenia mogą w ogóle nie zostać uruchomione. Ten wariant -execzawsze zwraca wartość true.

-execdir Komenda ;

-execdir Komenda {} +

Podobnie -exec, ale określone polecenie jest uruchamiane z podkatalogu zawierającego dopasowany plik, który zwykle nie jest katalogiem, w którym zacząłeś znajdować. Jest to znacznie bezpieczniejsza metoda wywoływania poleceń, ponieważ pozwala uniknąć warunków wyścigu podczas rozwiązywania ścieżek do dopasowanych plików. Podobnie jak w przypadku -exec akcji, + forma -execdir utworzy wiersz poleceń do przetworzenia więcej niż jednego dopasowanego pliku, ale każde wywołanie polecenia wyświetli tylko pliki, które istnieją w tym samym podkatalogu. Jeśli skorzystasz z tej opcji, musisz upewnić się, że twoja $PATHzmienna środowiskowa nie odwołuje się.; w przeciwnym razie atakujący może uruchomić dowolne polecenia, pozostawiając odpowiednio nazwany plik w katalogu, w którym będziesz działać -execdir. To samo dotyczy wpisów, $PATHktóre są puste lub które nie są absolutnymi nazwami katalogów. Jeśli findwystąpi błąd, może to czasami spowodować natychmiastowe wyjście, więc niektóre oczekujące polecenia mogą w ogóle nie zostać uruchomione. Wynik działania zależy od tego, +czy ;używany jest wariant lub ; -execdir polecenie {} + zawsze zwraca true, a -execdir polecenie {} ; zwraca true tylko wtedy, gdy polecenie zwraca 0.

man xargs

-I replace-str

Zamień wystąpienie replace-str w argumentach początkowych na nazwy odczytane ze standardowego wejścia. Ponadto, niecytowane puste miejsca nie kończą elementów wejściowych; zamiast tego separatorem jest znak nowej linii. Implikuje -xi -L 1.

-i[ replace-str ], --replace[ =replace-str ]

Ta opcja jest synonimem -Ireplace-str, jeśli podano replace-str . Jeśli brakuje argumentu replace-str , efekt jest taki sam jak -I{}. Ta opcja jest przestarzała; użyj -Izamiast tego.

Edytuj: a tutaj DLACZEGO bash ignoruje te nawiasy klamrowe:

man bash

{ lista; }

lista jest po prostu wykonywana w bieżącym środowisku powłoki. lista musi być zakończona znakiem nowej linii lub średnikiem. Jest to znane jako polecenie grupowe. Status powrotu to status wyjścia z listy. Zauważ, że w przeciwieństwie do metaznaków ( i ) , { i } są słowami zastrzeżonymi i muszą wystąpić, gdy słowo zastrzeżone może zostać rozpoznane. Ponieważ nie powodują podziału słów, muszą być oddzielone od listy spacją lub innym metaznakiem powłoki.

Dla podkreślenia: lista musi być zakończona znakiem nowej linii lub średnikiem .


1
Dziękuję Ci! Jestem zirytowany tym, że ktokolwiek napisał, man xargsnie zadał sobie nawet trudu, aby wyjaśnić, co {}tak naprawdę znaczy, ani też autor nie przekierował czytelnika (bez zamierzonej gry słów) na wyjaśnienie -execna stronie podręcznika użytkownika find.
Niko Gambt

@NikoGambt - Współczuję ...
dzwonię

5
@NikoGambt Cóż, {} tak naprawdę nic nie znaczy dla xargs, z wyjątkiem tego, że jest domyślną wartością -i, która jest przestarzała. Nie jestem pewien, jakie wyjaśnienie jest konieczne poza tym. W opublikowanym przykładzie równie dobrze mogło być xargs -Iab echo ab; jest to całkowicie arbitralny wybór.
Random832

@ Random832 Po kilku dodatkowych testach -I, teraz rozumiem, co właściwie robi ta opcja. Tak, {}jest to arbitralne, jak powiedziałeś. Wyjaśniło mnie to If the replace-str argument is missing, the effect is the same as -I{}. Jeśli -Ibez argumentu byłyby takie same jak -I{}, cat foo | xargs -I echo {}spowodowałoby to taki sam wynik jak uruchomienie cat foo | xargs -I{} echo {}. Jednak nie są takie same. To pierwsze jest błędem, a tym bardziej pomylił mnie komunikat o błędzie xargs: {}: No such file or directory, ale to tylko z powodu implementacji.
Niko Gambt

1
@NikoGambt -I(wielka litera I) nie może być uruchamiany bez argumentu. Argumentem -Ibyło echo. Jest to podstawowa różnica między -Ii -i(i powodem, dla którego -i jest przestarzałe, ponieważ opcje z
niepotrzebnymi
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.