W dokumentacji widzę użycie na dwa sposoby:
find . -type f -exec file '{}' \;
find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \
W dokumentacji widzę użycie na dwa sposoby:
find . -type f -exec file '{}' \;
find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \
Odpowiedzi:
Do bash
powłoki '{}'
i {}
są wymienne. Nie jest tak w przypadku wszystkich powłok (takich jak fish
).
Umieszczenie argumentu w pojedynczych cudzysłowach wyraźnie wskazuje, że nawiasy klamrowe powinny zostać wysłane do find
. W zależności od użycia powłoka bash czasami zastępuje zawartość nawiasów klamrowych.
Jak widać poniżej, bash nie zastępuje pustych nawiasów i są przekazywane do polecenia. Dla find
polecenia to nie ma znaczenia.
$ echo {}
{}
$ echo {1}
{1}
$ echo {1,3}
1 3
$ echo '{1,3}'
{1,3}
" are interchangeable"
z " are interchangeable in some shells, not in all of them. ALWAYS use the single quotes to make sure they get passed as-is to the find command"
(dobrych nawyków rozpoczyna upewniając użyć właściwą drogę nawet jeśli zdarzy się (zawsze) będzie na systemie, który pozwala na dwuznaczne jeden?)
Przy prawie wszystkich dostępnych interpretatorach powłok nie ma absolutnie żadnej różnicy między '{}'
i {}
.
Pojedyncze cudzysłowy są zwykle używane do ochrony osadzonego ciągu przed zastąpieniem go przez coś innego, na przykład:
'a b'
to parametr składający się z trzech znaków, bez cudzysłowów, które byłyby dwoma parametrami z jednym znakiem'$b'
to dosłownie znak dolara, po którym następuje litera b, bez cudzysłowu, który byłby czymkolwiek, co zawiera zmienna b, i być może nic, gdyby nie była ustawiona'!!'
są wykrzyknikami w literaturze, gdy nie są cytowane, a przy niektórych interaktywnych powłokach rozwiną się do ostatniego polecenia w historii'*'
jest literą literalną, bez cudzysłowu zastąpiłaby ją lista ukrytych nazw plików w bieżącym katalogu.Ponieważ ani ze standardem POSIX ani muszli nurtu ( sh
(Bourne), ksh
, bash
, ash
, dash
, zsh
, csh
, tcsh
) rozwinąć {}
się do czegoś innego, cytaty nie są wymagane.
Istnieje jednak egzotyczna powłoka o nazwie fish
, która rozwija się {}
jako pusty ciąg znaków, np .:
> ps -p %self
PID TTY TIME CMD
5247 pts/1 00:00:00 fish
> echo a {} b '{}'
a b {}
Jest to prawdopodobnie powód, dla którego find
dokumentacja GNU sugeruje ochronę {}
przed interpretacją za pomocą cytatów lub ukośników odwrotnych.
Dla większości użytkowników (szczególnie tych używających powłok POSIX) nie ma różnicy.
Zgodnie z sekcją Przykład strony podręcznika dla GNU find
:
Zauważ, że nawiasy klamrowe są ujęte w znaki pojedynczego cudzysłowu, aby chronić je przed interpretacją jako interpunkcji skryptu powłoki.
Myślę, że autorzy strony podręcznika GNU popełniają błędy po stronie ostrożności, ale zauważam, że nie wszystkie przykłady na stronie podręcznika cytują nawiasy klamrowe. Te przykłady z oficjalnej dokumentacji znalezienia GNU również pomijają cytowanie.
W przykładach ze specyfikacji POSIX / Single UNIX nawiasy klamrowe nie są cytowane, gdy są używane z -exec
opcją.
W przypadku powłoki POSIX ekspansja parametrów występuje tylko wtedy, gdy w nawiasach znajdują się specjalne parametry - ale nie w pustych nawiasach .
Powłoka Bash zawiera rozwinięcie nawiasu jako funkcję (nieprzenośną), ale takie wzory są rozwijane tylko wtedy, gdy w nawiasach znajdują się przecinek lub kropki . Bash używa również nawiasów klamrowych do grupowania poleceń , ale nie dzieje się tak, chyba że faktycznie istnieje grupa poleceń w nawiasach klamrowych.
Wreszcie, próbowałem działa find -exec ls -l {} \;
w sh
, dash
a tcsh
jednak żaden z tych muszli rozszerzono również {}
na cokolwiek innego. Jak zauważyli inni, fish
powłoka traktuje {}
specjalnie, ale nie jest to powłoka POSIX (co jej twórcy i użytkownicy uważają za zaletę). To nie zaszkodzi zacytować szelki ale maszynistki leniwych, którzy nie korzystają z skorupiaków nie powinien czuć się winny ich pominięcia.
'{}'
zamiast {}
), aby ich powłoka wysłała {}
polecenie find bez interpretowania go (jak wspomniano powyżej przez @ Charles-Duffy, jeśli zdarzy się, że używasz ryb , to zinterpretuje, {}
ale nie '{}'
, więc musisz użyć tego drugiego na tej powłoce (i kilku innych!). Dlatego zawsze używaj, '{}'
aby uniknąć ukąszenia przez dwuznaczność{}
To zależy od składni twojej powłoki. W razie wątpliwości powtórz to!
Uruchomić to
echo '{}'
i to.
echo {}
Jeśli generują ten sam wynik, odpowiedź dla twojej powłoki brzmi: tak. Jak zauważyli inni, przynajmniej będzie tak w bashu, a nie w rybach. Dane wyjściowe są tym, do czego należy zajrzeć na stronę podręcznika danego polecenia.
Jeśli chcesz się przydać, możesz nawet prefiksować echo
całą linię poleceń, aby zobaczyć rzeczywiste polecenie wraz ze wszystkimi argumentami, które faktycznie wywoła twoja powłoka. Uważaj jednak, że lista zawierająca polecenie plus argumenty to prawdziwa tablica ciągów znaków, każda być może pusta lub z białymi spacjami, ale echo wypisuje ją niejednoznacznie jako listę oddzieloną spacjami.
Jak można zweryfikować za pomocą tej nieco bardziej szczegółowej komendy echo (pokazującej argumenty cytowane w guillemet),
#!/bin/sh
for a in "$@"; do
printf '«%s» ' "$a"
done
echo ''
wpisując to w wierszu poleceń,
find 'My Documents and Settings' -type f -exec file {} \;
oznacza to bash:
«find» «My Documents and Settings» «-type» «f» «-exec» «file» «{}» «;»
a to u ryb:
«find» «My Documents and Settings» «-type» «f» «-exec» «file» «» «;»
Jako ogólna rada, nigdy nie boli cytować.