Differenza tra '{}' e {} nel comando find?


18

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 ; \

4
Certo sembra che non abbia nulla a che fare con il comando find, e invece abbia a che fare con la corretta quotazione del comando chiamato.
Zoredache,

1
Provalo con il pesce, piuttosto che bash.
Charles Duffy,

Risposte:


24

Per la bashshell '{}'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 findcomando, non importa.

$ echo {}
{}

$ echo {1}
{1}

$ echo {1,3}
1 3

$ echo '{1,3}'
{1,3}

4
Non importa con bash. Importa con i pesci.
Charles Duffy,

1
Sostituirei " 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)
Olivier Dulac,

9

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 finddocumentazione GNU suggerisce di proteggere {}dall'interpretazione con virgolette o barre rovesciate.


9

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' -execopzione.

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, dashe tcshma nessuno di questi gusci ampliato il {}in qualsiasi altra cosa. Come altri hanno sottolineato, la fishshell 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.


non stanno commettendo errori, stanno cercando di assicurarsi che le persone usino il modo corretto (cioè usano '{}'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{}
Olivier Dulac,

6

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 echoun 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.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.