Nella documentazione , vedo l'utilizzo in entrambi i modi:
find . -type f -exec file '{}' \;
find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \
Nella documentazione , vedo l'utilizzo in entrambi i modi:
find . -type f -exec file '{}' \;
find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \
Risposte:
Per la bash
shell '{}'
e {}
sono intercambiabili. Questo non è il caso di tutte le shell (come fish
).
Mettere l'argomento tra virgolette singole indica esplicitamente che le parentesi graffe devono essere inviate a find
. A seconda dell'uso, la shell bash a volte sostituisce il contenuto delle parentesi graffe.
Come visto di seguito, bash non sostituisce parentesi vuote e vengono passati al comando. Per il find
comando, non importa.
$ echo {}
{}
$ echo {1}
{1}
$ echo {1,3}
1 3
$ echo '{1,3}'
{1,3}
" are interchangeable"
con " 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"
(le buone abitudini iniziano assicurandoti di usare il modo corretto anche se ti capita (sempre?) Di essere su un sistema che consente quello ambiguo)
Con quasi tutti gli interpreti di shell disponibili, non c'è assolutamente alcuna differenza tra '{}'
e {}
.
Le virgolette singole vengono normalmente utilizzate per proteggere la stringa incorporata dall'essere sostituita da qualcos'altro, ad esempio:
'a b'
è un parametro a tre caratteri singolo, senza virgolette che sarebbero due parametri a carattere singolo'$b'
è letteralmente il simbolo del dollaro seguito dalla lettera b, senza la citazione che sarebbe qualunque cosa la variabile b contenga e possibilmente nulla se non impostata'!!'
sono punti esclamativi letterali mentre non quotati e con alcune shell interattive, si espandono fino all'ultimo comando inserito nella cronologia'*'
è un asterisco litterico, senza virgoletta verrà sostituito dall'elenco di nomi di file non nascosti nella directory corrente.Poiché né lo standard POSIX né le conchiglie tradizionali ( sh
(Bourne), ksh
, bash
, ash
, dash
, zsh
, csh
, tcsh
) può estendere {}
a qualcos'altro, le citazioni non sono richiesti.
Tuttavia, esiste un guscio esotico, chiamato fish
, che si espande {}
come una stringa vuota, ad esempio:
> ps -p %self
PID TTY TIME CMD
5247 pts/1 00:00:00 fish
> echo a {} b '{}'
a b {}
Questo è probabilmente il motivo per cui la find
documentazione GNU suggerisce di proteggere {}
dall'interpretazione con virgolette o barre rovesciate.
Per la maggior parte degli utenti (in particolare quelli che usano shell POSIX), non c'è differenza.
Secondo la sezione Esempio della pagina man di GNU find
:
Si noti che le parentesi graffe sono racchiuse tra virgolette singole per proteggerle dall'interpretazione come punteggiatura di script shell.
Penso che gli autori della pagina man GNU stiano errando con cautela, ma noto che non tutti gli esempi nella loro pagina man citano le parentesi graffe. Questi esempi tratti dalla documentazione ufficiale di GNU trovano anche la citazione.
Negli esempi delle specifiche POSIX / Single UNIX le parentesi graffe non vengono citate se utilizzate con l' -exec
opzione.
Con una shell POSIX, l' espansione dei parametri si verifica solo quando ci sono parametri speciali racchiusi tra parentesi graffe, ma non con parentesi vuote .
La shell Bash include l' espansione delle parentesi graffe come funzione (non portatile), ma tali modelli vengono espansi solo quando una virgola o punti sono inclusi tra parentesi graffe . Bash utilizza anche bretelle per comando raggruppamento , ma ciò non si verifica a meno che effettivamente esiste è un gruppo di comandi all'interno del tutore.
Infine, ho provato a fare funzionare find -exec ls -l {} \;
in sh
, dash
e tcsh
ma nessuno di questi gusci ampliato il {}
in qualsiasi altra cosa. Come altri hanno sottolineato, la fish
shell tratta in modo {}
speciale ma questa non è una shell POSIX (che i suoi creatori e utenti considerano un vantaggio). Non fa male citare le parentesi graffe, ma i dattilografi pigri che non usano il guscio di pesce non dovrebbero sentirsi in colpa per ometterle.
'{}'
invece di {}
) in modo che la loro shell invii {}
al comando find senza interpretarlo (come menzionato sopra da @ Charles-Duffy, se ti capita di usare il pesce , interpreterà {}
ma non '{}'
, quindi è necessario utilizzare quest'ultimo su quella shell (e su molti altri!). Pertanto, utilizzare sempre '{}'
per evitare di essere morso dall'ambiguità di{}
Questo dipende dalla sintassi della shell. In caso di dubbio, fai eco!
Esegui questo
echo '{}'
e questo.
echo {}
Se producono lo stesso output, la risposta per la tua shell è sì. Come altri hanno notato, sarà almeno sì nella bash e no nei pesci. L'output è ciò per cui dovresti consultare la manpage di un dato comando.
Se vuoi essere utile, puoi anche aggiungere echo
un prefisso a un'intera riga di comando, per vedere il comando effettivo , con tutti i suoi argomenti, che la tua shell invocherebbe effettivamente. Attenzione, però, che l'elenco che comprende il comando più argomenti è un vero array di stringhe, ognuna possibilmente vuota o con spazi bianchi, eppure l'eco lo stampa in modo ambiguo come un elenco separato da spazi.
Come si può verificare con questo comando echo leggermente più dettagliato (che mostra argomenti citati da Guillemet),
#!/bin/sh
for a in "$@"; do
printf '«%s» ' "$a"
done
echo ''
digitandolo sulla riga di comando,
find 'My Documents and Settings' -type f -exec file {} \;
significa che bash:
«find» «My Documents and Settings» «-type» «f» «-exec» «file» «{}» «;»
e questo nei pesci:
«find» «My Documents and Settings» «-type» «f» «-exec» «file» «» «;»
Come consiglio generale, non fa mai male citare.