Dans le terminal d'Ubuntu 18.04 LTS, lorsque j'écris cette commande:
echo -e "Hello\\\n"
Il donne ceci en sortie:
Hello\n
Mais il devrait s'imprimer, comme le dit la page de manuel :
Hello\
Autrement dit, imprimez d'abord Hello
, puis \
, un caractère de nouvelle ligne (puis une autre nouvelle ligne). Où est le problème?
Voir ces quelques echo -e
commandes et leur sortie :
man420@man420-X542UQ:~$ echo -e "HEllo\a\a\a\a\a\a\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\\\n"
HEllo\n
man420@man420-X542UQ:~$ echo -e "HEllo\a\\\n"
HEllo\n
command-line
echo
yolin00
la source
la source
echo
en premier lieu: utiliserprintf
.Réponses:
Les barres obliques inverses sont traitées spécialement par
echo -e
, mais d'abord elles sont parfois traitées spécialement par le shell (qui dans ce cas estbash
), selon les règles de citation du shell .L'argument
echo
voit réellement estHello\\n
. Parce que vous êtes passé-e
àecho
, il traite les échappements antislash spécialement et\\
est réduit à un seul\
. La finalen
n'est pas échappée, elle apparaît donc littéralement.La raison en est que, avant et indépendamment de son fonctionnement
echo
, le shell traite\
spécialement dans certains contextes mais pas dans d'autres. Les\
caractères entre guillemets sont toujours traités spécialement, les guillemets simples\
ne sont jamais traités spécialement, mais le traitement des caractères entre guillemets\
, comme dans la commande que vous avez exécutée, est plus subtil et compliqué.Lorsque le shell rencontre du texte entre guillemets doubles dans une commande, comme avec
"Hello\\\n"
, il traite\
comme un caractère d'échappement lorsqu'il précède un caractère qui peut lui-même avoir une signification particulière à l'intérieur des guillemets doubles et pas autrement .\
parfois a une signification particulière à l'intérieur""
, un\
qui précède immédiatement un autre\
a pour effet de citer cette seconde\
. Donc, à l'intérieur des guillemets doubles, les premiers\\
sont regroupés\
.\
caractères, il y a un troisième\
caractère qui n'est pas affecté par ces deux premiers et qui précède unn
. Mais cen
n'est pas un personnage qui est jamais traité spécialement à l'intérieur de guillemets doubles, donc\
avant il n'est pas traité spécialement dans cette situation.\n
Reste ainsi\n
.L'effet est que, entre guillemets,
\\\n
est interprété comme\\n
.Quand
echo -e
voit\\n
, le premier\
supprime la signification spéciale du second,echo
imprime donc\n
littéralement pour ce texte.Si votre objectif est d'imprimer
Hello
avec une nouvelle ligne supplémentaire mais sans barre oblique inverse (la question était à l'origine ambiguë à ce sujet, et je pense que c'est un exemple utile), alors une solution consiste à supprimer a\
. Exécution desecho -e "Hello\\n"
sortiesHello
avec une nouvelle ligne supplémentaire à la fin.Une meilleure solution consiste à utiliser des guillemets simples et à écrire
echo -e 'Hello\n'
. Les guillemets simples sont la forme de devis la plus puissante. Une solution encore meilleure consiste généralement à utiliser à laprintf
place deecho
, ce qui serait le cas dans ce casprintf 'Hello\n\n'
.Si votre objectif est d'imprimer,
Hello\
y compris la barre oblique inverse, suivie d'une nouvelle ligne supplémentaire , l'approche à guillemets doubles est possible mais lourde. Pour le comprendre, travaillez en arrière:echo -e
convertit\\
en\
et\n
vers une nouvelle ligne, et les guillemets doubles convertis\\
en\
, vous pouvez donc le faire avec six barres obliques inverses (echo -e "Hello\\\\\\n"
), car\\n
se transforme en\n
une barre oblique inversée en échappant une autre. Vous pouvez également le faire avec cinq, car les guillemets doubles sont conservés\n
lorsque le\
n'est pas échappé.Cela illustre les avantages des guillemets simples: mettez simplement ce que vous voulez
echo -e
voir à l'intérieur des guillemets simples (echo -e 'Hello\\\n'
).printf
est également bon ici. Une option estprintf 'Hello\\\n\n'
. Mais ceprintf
qui brille vraiment, c'est que vous pouvez ajouter des arguments supplémentaires. Vous pouvez utiliserprintf '%s\n\n' 'Hello\'
, qui insère le deuxième argument (littéralementHello\
parce que les guillemets simples ne changent rien) à la place de%s
.la source