Comment échappez-vous à l'apostrophe dans une chaîne entre guillemets simples dans bash?

18

Je ne comprends pas comment bash évalue l'échappement de caractères d'apostrophe dans des chaînes entre guillemets simples.

Voici un exemple:

$ echo ''\''Hello World'\'''
'Hello World' # works

$ echo '\'Hello World\''
 > # expects you to continue input

J'ai essayé de chercher des explications à cela, mais je n'ai rien pu obtenir. Que fait bash ici?

Kibet
la source
echo \''Hello World'\'
math

Réponses:

19

Dans les guillemets simples, aucun échappement n'est possible. Il n'y a aucun moyen d'inclure un guillemet simple dans des guillemets simples. Voir Citation dans man bash .

choroba
la source
1
Tu as raison. L'astuce réside dans cette ligne: «Un guillemet simple ne peut pas se produire entre des guillemets simples, même lorsqu'il est précédé d'une barre oblique inverse».
Kibet
@Colin Dès qu'une citation simple se trouve à l'intérieur de deux autres guillemets simples (mais annulée), la citation citée n'est plus une vraie citation. C'est juste un char sans caractéristiques d'appariement spéciales.
zero2cx
1
@ zero2cx: Pas vrai:echo '\''
choroba
@ zero2cx: je dirais "extérieur" au lieu de "intérieur".
choroba
3
@choroba pas "totalement" vrai, en bash vous pouvez le faireecho $'\'hello world\''
bufh
9

En plus des bashguillemets simples et doubles pris en charge par POSIX, fournit un type supplémentaire de guillemets pour autoriser une petite classe de caractères d'échappement (y compris un guillemet simple) dans une chaîne entre guillemets:

$ echo $'\'Hello World\''
'Hello World'

Voir la section QUOTING dans la bashpage de manuel, vers la fin de la section. (Recherchez "ANSI C".)

chepner
la source
3

Pour expliquer ce qui se passe avec vos apostrophes échappées, nous examinerons votre deuxième exemple (voir également les guillemets simples ou les guillemets forts ):

$ echo '\'Hello World\''
>     # expects you to continue input

Ici, vous avez laissé la citation suspendue, comme vous l'avez dit. Maintenant, coupez l'extrémité et changez-la en:

                     v                                v           v
$ echo '\'Hello World     # Echo two strings: '\' and 'Hello World'.
\Hello World         ^

La sous-chaîne "Hello World" n'était pas citée ici, mais elle se comportait comme si elle était fortement citée. En utilisant à nouveau votre exemple, coupez la fin différemment cette fois:

                     vv                                    v (plain apostrophe)
$ echo '\'Hello World\'   # Will echo: '\' and 'Hello World''
\Hello World'        ^^   # Note that the trailing ' char is backslash escaped. 

La sous-chaîne "Hello World" se comporte à nouveau comme si elle était entre guillemets forts, avec seulement l'apostrophe ajoutée (échappée, donc plus une seule citation) à la fin.

Lorsqu'un autre guillemet simple est ajouté à la fin (votre exemple d'origine), la chaîne reste suspendue et attend un guillemet de fermeture.

zero2cx
la source
3

Exemple simple d'échapper des guillemets dans le shell:

$ echo 'abc'\''abc'
abc'abc
$ echo "abc"\""abc"
abc"abc

Pour ce faire, fermez un ( ') déjà ouvert , placez un ( \') échappé à imprimer, puis ouvrez-en un autre ( ').

Alternativement:

$ echo 'abc'"'"'abc'
abc'abc
$ echo "abc"'"'"abc"
abc"abc

Cela se fait en terminant un ( ') déjà ouvert , en plaçant un guillemet dans un autre guillemet ( "'"), puis en ouvrant un autre ( ').

Ce que vous avez fait ( '\'Hello World\''), c'est:

  1. Ouvert 1er apostrophe: '.
  2. Fermé juste après \', de sorte que la chaîne devient: '\'.
  3. Hello World n'est pas des guillemets.
  4. Apostrophe autonome placée ( \') sans l'ouvrir.
  5. La dernière apostrophe ( ') est une chaîne d'ouverture, mais aucune fermeture n'est attendue.

Ainsi, l'exemple correct serait:

$ echo \'Hello World\'
'Hello World'

Connexe: Comment échapper les guillemets simples dans les chaînes entre guillemets simples?

kenorb
la source