Différence entre '{}' et {} dans la commande find?


18

Dans la documentation , je vois l'utilisation dans les deux sens:

find . -type f -exec file '{}' \;

find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \

4
Bien sûr, il semble que cela n'a rien à voir avec la recherche, la commande et plutôt à la citation appropriée pour la commande appelée.
Zoredache

1
Essayez-le avec du poisson, plutôt que bash.
Charles Duffy

Réponses:


24

Pour la bashcoque, '{}'et {}sont interchangeables. Ce n'est pas le cas avec tous les obus (comme fish).

Mettre l'argument entre guillemets indique explicitement que les accolades doivent être envoyées à find. Selon l'utilisation, le shell bash remplace parfois le contenu des accolades.

Comme vu ci-dessous, bash ne remplace pas les crochets vides et ils sont passés à la commande. Pour la findcommande, cela n'a pas d'importance.

$ echo {}
{}

$ echo {1}
{1}

$ echo {1,3}
1 3

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

4
Peu importe avec bash. Est important pour le poisson.
Charles Duffy

1
Je remplacerais " are interchangeable"par " 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"(les bonnes habitudes commencent en s'assurant que vous utilisez la bonne façon même s'il vous arrive (toujours?) D'être sur un système qui autorise l'ambiguïté)
Olivier Dulac

9

Avec presque tous les interpréteurs shell disponibles, il n'y a absolument aucune différence entre '{}'et {}.

Les guillemets simples sont normalement utilisés pour protéger la chaîne incorporée contre la substitution par quelque chose d'autre, par exemple:

  • 'a b' est un seul paramètre de trois caractères, sans les guillemets qui seraient deux paramètres de caractère unique
  • '$b' est littéralement le signe dollar suivi de la lettre b, sans la citation qui serait ce que la variable b contient et éventuellement rien si elle n'est pas définie
  • '!!' sont des points d'exclamation littéraux sans guillemets et avec certains shells interactifs, ils se développeraient jusqu'à la dernière commande mise dans l'histoire
  • '*' est un astérisque littéral, sans guillemets, il serait remplacé par la liste des noms de fichiers non cachés dans le répertoire courant.

Comme ni la norme ni les coquilles POSIX traditionnels ( sh(Bourne), ksh, bash, ash, dash, zsh, csh, tcsh) étendre {}à autre chose, les citations ne sont pas nécessaires.

Cependant, il existe un shell exotique, nommé fish, qui se développe {}comme une chaîne vide, par exemple:

> ps -p %self
  PID TTY          TIME CMD
 5247 pts/1    00:00:00 fish
> echo a {} b '{}'
a  b {}

C'est probablement la raison pour laquelle la finddocumentation GNU suggère de se protéger {}contre l'interprétation avec des guillemets ou des barres obliques inverses.


9

Pour la plupart des utilisateurs (en particulier ceux qui utilisent des shells POSIX), il n'y a pas de différence.

Selon la section Exemple de la page de manuel de GNU find:

Notez que les accolades sont placées entre guillemets simples pour les protéger de l'interprétation en tant que ponctuation de script shell.

Je pense que le ou les auteurs de la page de manuel GNU se trompent de prudence, mais je note que tous les exemples de leur page de manuel ne citent pas les accolades. Ces exemples tirés de la documentation officielle de GNU find omettent également les citations.

Dans les exemples de la spécification POSIX / Single UNIX, les accolades ne sont pas citées lorsqu'elles sont utilisées avec l' -execoption.

Avec un shell POSIX, l' expansion des paramètres se produit uniquement lorsqu'il y a des paramètres spéciaux entre accolades - mais pas avec des accolades vides .

Le shell Bash inclut l' expansion des accolades en tant que fonctionnalité (non portable), mais ces modèles ne sont développés que lorsqu'une virgule ou des points sont inclus dans les accolades . Bash utilise également des accolades pour le regroupement de commandes , mais cela ne se produit pas à moins qu'il y fait est un groupe de commandes dans l'accolade.

Enfin, j'ai essayé de courir find -exec ls -l {} \;dans sh, dashet , tcshmais aucune de ces obus a élargi le {}dans quoi que ce soit d' autre. Comme d'autres l'ont souligné, le fishshell est {}spécialement traité mais ce n'est pas un shell POSIX (que ses créateurs et utilisateurs considèrent comme un avantage). Il ne fait aucun mal de citer les accolades, mais les dactylos paresseux qui n'utilisent pas la coquille de poisson ne devraient pas se sentir coupables de les avoir omis.


ils ne se trompent pas, ils essaient de s'assurer que les gens utilisent la bonne façon (c'est-à-dire à la '{}'place de {}) afin que leur shell envoie {}à la commande find sans l'interpréter (comme mentionné ci-dessus par @ Charles-Duffy, s'il vous arrive d'utiliser du poisson , il interprétera {}mais pas '{}', vous devez donc utiliser ce dernier sur ce shell (et sur plusieurs autres!). Par conséquent, utilisez toujours '{}'pour éviter d'être mordu par l'ambiguïté de{}
Olivier Dulac

6

Cela dépend de la syntaxe de votre shell. En cas de doute, faites-le écho!

Lance ça

echo '{}'

et ça.

echo {}

S'ils produisent la même sortie, la réponse pour votre shell est oui. Comme d'autres l'ont noté, ce sera au moins oui en bash et non en poisson. La sortie est la raison pour laquelle vous devriez consulter la page de manuel d'une commande donnée.


Si vous voulez être pratique, vous pouvez même préfixer echoune ligne de commande entière, pour voir la commande réelle , avec tous ses arguments, que votre shell invoquerait réellement. Attention cependant, la liste comprenant la commande plus les arguments est un véritable tableau de chaînes, chacune éventuellement vide ou avec des espaces, mais écho l'imprime de manière ambiguë comme une liste séparée par des espaces.

Comme cela peut être vérifié avec cette commande d'écho légèrement plus verbeuse (montrant les arguments cités par guillemet),

#!/bin/sh
for a in "$@"; do
    printf '«%s» ' "$a"
done
echo ''

en tapant ceci sur la ligne de commande,

find 'My Documents and Settings' -type f -exec file {} \;

signifie que bash:

«find» «My Documents and Settings» «-type» «f» «-exec» «file» «{}» «;»

et cela chez les poissons:

«find» «My Documents and Settings» «-type» «f» «-exec» «file» «» «;»

Comme conseil général, ça ne fait jamais de mal de citer.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.