Quels caractères doivent être échappés dans les arguments de command line?

Dans Bash, lors de la spécification d'arguments de command line à une command, quels caractères doivent être échappés?

Sont-ils limités aux métacaractères de Bash: space, tab, '|', '&', ';', '(', ')', '<' ou '>'?

Les caractères suivants ont une signification spéciale pour le shell lui-même dans certains contexts et peuvent avoir besoin d'être échappés dans les arguments:

  • ` Backtick (U + 0060 accent grave)
  • ~ Tilde (U + 007E)
  • ! Point d'exclamation (U + 0021)
  • # Hash (signe de numéro U + 0023)
  • $ Signe dollar (U + 0024)
  • & Esperluette (U + 0026)
  • * Astérisque (U + 002A)
  • ( Parenthèse gauche (U + 0028)
  • ) Parenthèse droite (U + 0029)
  • ( ) Onglet (U + 0009)
  • { Brace gauche (U + 007B Bride gauche)
  • [ Équerre de gauche (U + 005B)
  • | Barre verticale (ligne verticale U + 007C)
  • \ Backslash (U + 005C Reverse Solidus)
  • ; Point-virgule (U + 003B)
  • ' Citation unique / Apostrophe (U + 0027)
  • " Double devis (U + 0022)
  • Nouvelle ligne (U + 000A)
  • < Moins que (U + 003C)
  • > Supérieur à (U + 003E)
  • ? Point d'interrogation (U + 003F)
  • Espace (U + 0020) 1

Certains de ces caractères sont utilisés pour plus de choses et dans plus d'endroits que celui que j'ai lié.


Il y a quelques cas de coin qui sont explicitement optionnels:

  • ! peut être désactivé avec set +H , qui est la valeur par défaut dans les shells non interactifs.
  • { peut être désactivé avec set +B
  • * et ? peut être désactivé avec set -f ou set -o noglob .
  • = signe égal (U + 003D) doit également être échappé si le set -o keyword set -k ou set -o keyword est activé.

Échapper à une nouvelle ligne nécessite de citer – les antislashs ne feront pas le travail. Tous les autres caractères listés dans IFS auront besoin d'une manipulation similaire. Vous n'avez pas besoin d'échapper ] ou } , mais vous avez besoin d'échapper ) parce que c'est un opérateur.

Certains de ces personnages ont des limites plus ssortingctes quand ils ont vraiment besoin d'échapper à d'autres. Par exemple, a#b est ok, mais a #b est un commentaire, alors que > devrait s'échapper dans les deux contexts. Il ne fait pas mal de les échapper de façon conservasortingce de toute façon, et c'est plus facile que de se callbacker les distinctions fines.

Si votre nom de command lui-même est un mot-key shell ( if , for , do ), vous devrez l'échapper ou le citer aussi. Le seul intéressant de ceux-ci est, parce qu'il n'est pas évident que c'est toujours un mot-key. Vous n'avez pas besoin de faire cela pour les mots-keys utilisés dans les arguments, seulement quand vous avez (follement!) Nommé une command après l'un d'entre eux. Les opérateurs Shell ( ( , & , etc) ont toujours besoin de citer où qu'ils se trouvent.


1 Stéphane a noté que tout autre caractère blanc à un octet de votre environnement local doit également s'échapper. Dans les environnements les plus communs, sensibles, au less ceux basés sur C ou UTF-8, ce sont seulement les caractères d'espace ci-dessus. Dans certains environnements ISO-8859-1, l'espace sans interruption U + 00A0 est considéré vide, y compris Solaris, les BSD et OS X (je ne pense pas correctement). Si vous avez affaire à un environnement local arbitraire, cela peut inclure n'importe quoi, y compris les lettres, alors bonne chance.

Il est concevable qu'un seul octet considéré vide puisse apparaître dans un caractère multi-octets qui n'était pas vide et que vous n'auriez aucun moyen d'y échapper autrement que de mettre le tout entre guillemets. Ce n'est pas une préoccupation théorique: dans un environnement local ISO-8859-1, l'octet A0 qui est considéré comme un blanc peut apparaître à l' intérieur de caractères multioctets comme UTF-8 codé "à" ( C3 A0 ). Pour gérer ces caractères en toute security, vous devez les citer "à" . Ce comportement dépend de la configuration des parameters régionaux dans l'environnement exécutant le script, pas celui où vous l'avez écrit.

Je pense que ce comportement est cassé de plusieurs façons, mais nous devons jouer la main que nous sums traités. Si vous travaillez avec un jeu de caractères multi-octets non auto-synchronisés, le plus sûr serait de tout citer. Si vous êtes en UTF-8 ou C, vous êtes en security (pour le moment).