GNU/Linux >> Tutoriels Linux >  >> Linux

La différence entre les guillemets "...", "...", $'...' et $"..." dans le shell ?

Parfois, je vois des scripts shell utiliser toutes ces différentes façons de citer du texte :"..." , '...' , $'...' , et $"..." . Pourquoi utilise-t-on autant de types de devis différents ?

Se comportent-ils différemment ou affectent-ils ce que je peux faire à l'intérieur ?

Réponse acceptée :

Tous ces éléments signifient quelque chose de différent, et vous pouvez écrire différentes choses à l'intérieur (ou les mêmes choses, avec une signification différente). Différents types de guillemets interprètent différentes séquences d'échappement à l'intérieur (something ), ou autorisez ou non les interpolations de variables ($something ) et d'autres types d'expansion à l'intérieur.

En bref :

  • '...' est entièrement littéral.
  • "..." autorise à la fois les variables et les guillemets intégrés.
  • $'...' effectue des échappements de caractères comme n , mais ne développe pas les variables.
  • $"..." est pour les traductions en langage humain dans Bash et ksh.

'Apostrophes'

Tout ce que vous écrivez entre guillemets simples est traité littéralement et pas du tout traité. Les barres obliques inverses et les signes dollar n'y ont aucune signification particulière. Cela signifie que vous ne pouvez pas échapper un caractère par une barre oblique inverse (y compris d'autres guillemets simples !), interpoler une variable ou utiliser toute autre fonctionnalité du shell.

Tous ces exemples donnent littéralement ce qui est écrit entre les guillemets :

Code Résultat
'hello world' bonjour le monde
'/pkg/bin:$PATH' /pkg/bin :$PATH
'hellonworld' hellonworld
'`echo abc`' `echo abc`
'I'dn't've' Je ne sais pas

Le dernier est compliqué - il y en a deux les chaînes entre guillemets simples sont exécutées avec du texte sans guillemets. Le premier contient I . Le texte sans guillemets dn't contient un guillemet simple qui est échappé au niveau du shell , donc il ne commence pas une chaîne entre guillemets et est inclus en tant que caractère littéral (donc, dn't ). La chaîne finale entre guillemets est juste ve . Tous ces éléments sont regroupés en un seul mot de la manière habituelle dont fonctionne le shell.

Un idiome assez courant pour combiner du texte littéral et des variables consiste à les exécuter ensemble comme ceci :

'let x="'$PATH"

entraînera

let x="/usr/bin:/bin"

comme un seul mot (mieux vaut mettre entre guillemets $PATH ainsi qu'au cas où - des espaces ou des caractères globaux dans la variable valeur peut être traité autrement - mais pour un exemple courant lisible, je ne l'ai pas fait).

« Guillemets doubles »

À l'intérieur des guillemets doubles, deux types d'expansion sont traités, et vous pouvez utiliser une barre oblique inverse pour échapper les caractères afin d'empêcher les expansions ou les échappements d'être traités.

Il existe deux catégories d'expansion qui se produisent à l'intérieur des guillemets :

  • Ceux commençant par $ (extension de paramètre $abc et ${abc} , substitution de commande $(...) , et développement arithmétique $((...)) );
  • Substitution de commandes avec guillemets inverses `abc`;

À l'intérieur des guillemets, une barre oblique inverse peut inhiber ces expansions en la plaçant avant le $ ou ` . Il peut également échapper à un guillemet double fermant, donc " inclut uniquement " dans votre chaîne, ou une autre barre oblique inverse. Toute autre barre oblique inverse est préservée littéralement - il n'y a pas d'échappement pour produire d'autres caractères, et elle n'est pas supprimée.

Certains de ces exemples agissent différemment d'avant, et d'autres non :

Code Résultat
"hello world" bonjour le monde
"/pkg/bin:$PATH" /pkg/bin:/bin:/usr/bin
"hellonworld" hellonworld
"hello\nworld" hellonworld
"`echo abc`" abc
"I'dn't've" Je n'aurais pas
"I'dn't've" Je n'aurais pas
"I"dn"t've" Je n'ai pas
Connexe :Dhcpv6 – avec état VS sans état, quelle est la différence entre cela ?

$'ANSI-C entre guillemets'

Ce type de guillemets permet de traiter les échappements antislash de style C, mais pas variables imbriquées ou substitutions. C'est le seul type de citation qui prend en charge les caractères d'échappement .

Il s'agit d'une extension de ksh, désormais prise en charge dans Bash, zsh et certains autres shells également. Il ne fait pas encore partie de la norme POSIX et les scripts les plus portables ne peuvent donc pas l'utiliser, mais un script Bash ou ksh est libre de le faire.

Tous ces échappements peuvent être utilisés avec leurs significations en C :a , b , f , n , r , t , v , et les échappements littéraux \ , ' , " , et ? . Ils prennent également en charge les extensions e (caractère d'échappement) et dans Bash et ksh cx (ce qui serait saisi par Ctrl-x, par exemple cM est un retour chariot). Les shells ont leur propre gamme d'extensions mineures.

Il permet également quatre types d'échappements de caractères génériques :

  • nnn , un seul octet avec une valeur octale nnn
  • xHH , un seul octet avec une valeur hexadécimale HH
  • uHHHH , le point de code Unicode dont l'index hexadécimal est HHHH
  • UHHHHHHHH , le point de code Unicode dont l'index hexadécimal est HHHHHHHH

Tous ces chiffres sont facultatifs après le premier.

$ et ` n'ont aucune signification et sont conservés littéralement, vous ne pouvez donc pas y inclure de variable.

Code Résultat
$'hello world' bonjour le monde
$'/pkg/bin:$PATH' /pkg/bin :$PATH
$'hellonworld' bonjour
monde
$'`echo abc`' `echo abc`
$'I'dn't've' Je n'aurais pas
$'U1f574u263A' 🕴☺

Vous pouvez simuler la plupart de ces évasions en utilisant le printf commande, bien que POSIX ne nécessite que \ , a , b , f , n , r , t , v , et nnn pour y travailler. Vous pouvez utiliser la substitution de commande pour intégrer un printf entre guillemets doubles si nécessaire :"Path:$(printf 't')$PATH" .

$"Traduction locale"

Il s'agit d'une extension spécifique à ksh et Bash pour localiser des chaînes textuelles en langage naturel et rechercher la partie à l'intérieur des guillemets dans un catalogue de messages. Il exécute d'abord tous les développements entre guillemets doubles. Si la chaîne n'est pas trouvée dans la base de données de traduction, elle est utilisée comme sa propre traduction. L'hypothèse intégrée est que les chaînes sont en anglais.

Vous ne voulez probablement pas utiliser celui-ci, mais si vous le voyez, vous pouvez généralement le traiter comme des guillemets doubles réguliers.

Un point à noter est qu'il n'y a pas type de citation qui permet à la fois l'expansion des paramètres intégrés et les échappements de caractères intégrés. Dans la plupart des cas où vous voudriez cela, vous feriez mieux (plus en sécurité) d'utiliser printf :

printf 'New path: e[1m%se[0m' "/pkg/bin:$PATH:"

Cela sépare clairement les parties soumises à l'échappement de caractères et celles qui sont des valeurs de données.

Une autre est que tous ces styles de guillemets créent un seul "mot" dans le shell, à moins que [email protected] ou une extension de tableau ${x[@]} est utilisé entre guillemets doubles. Les deux formes de guillemet simple sont toujours un mot et ne sont jamais développées davantage.


Linux
  1. La différence d'utilisation entre les variables shell et les variables d'environnement ?

  2. La différence entre Getty et Agetty ?

  3. La différence entre .exrc et .vimrc ?

  4. Linux – Quelle est la différence entre `su -` et `su –login` ?

  5. La Différence Entre Nss Et Pam?

Quelle est la différence entre Linux et Unix ?

Quelle est la différence entre la connexion et le shell sans connexion

La Différence Entre [[ $a ==Z* ]] Et [ $a ==Z* ] ?

Quelle est la différence entre Sudo Su - et Sudo Su - ?

Quelle est la différence entre une console, un terminal et un shell ?

Quelle est la différence entre ls et l ?