8 votes

Dans un Shell Linux, pourquoi le backslash-newline n'introduit-il pas d'espace ?

Lorsque j'utilise le Shell de Linux, je me retrouve dans la situation suivante :

$ A=B\
> C
$ echo $A
BC

Dans mon esprit, lorsque la nouvelle ligne rencontre un caractère d'échappement, il ne peut s'agir d'un caractère CR mais il s'agit toujours d'une nouvelle ligne. Le site echo $A devrait être interprété comme echo B newline C et le saut de ligne doit être un IFS pour echo . La sortie devrait donc être B C au lieu de BC .

Pourquoi est-ce que j'obtiens les résultats que j'obtiens ?

9voto

Daniel Beck Points 105590

Citation : man bash , section CITATION :

Une barre oblique inverse non citée ( \ ) est le caractère d'échappement. Il conserve la valeur littérale du caractère qui suit, à l'exception de <newline> . Si un \<newline> apparaît, et que la barre oblique inverse n'est pas elle-même citée, l'option \<newline> est traitée comme une continuation de ligne (c'est-à-dire qu'elle est retirée du flux d'entrée et effectivement ignorée).

Cela vous permet de briser les très longues commandes / séquences de commandes (piping et transformation de la sortie etc.) dans les scripts en plusieurs lignes pour plus de lisibilité.


Pour qu'il traite la nouvelle ligne comme vous le souhaitez, il suffit de mettre la valeur (et toute utilisation ultérieure de la variable) entre guillemets.

$ A="B
> C"
$ echo "$A"
B
C

De la même section :

Le fait d'enfermer les caractères entre guillemets simples préserve la valeur littérale de chaque caractère à l'intérieur des guillemets. ...

Le fait d'enfermer des caractères entre guillemets doubles préserve la valeur littérale de tous les caractères à l'intérieur des guillemets, à l'exception de $, `, \ et, lorsque l'extension de l'historique est activée, ! Les caractères $ et ` conservent leur signification particulière entre guillemets doubles. La barre oblique inversée ne conserve sa signification spéciale que si elle est suivie de l'un des caractères suivants : $, `, ", \ ou .

3voto

Volker Siegel Points 1332

Répondre au "pourquoi" par "pourquoi est-ce utile" :

Le Backslash-newline est utilisé pour continuation de la ligne pour diviser de trop longues files d'attente :

Un backslash à la fin d'une ligne dans un Shell Shell fait que le Shell ignore la nouvelle ligne dans le but d'exécuter le Shell. Ceci est normalement utilisé pour diviser de longues lignes dans un fichier Shell en plusieurs lignes de texte, qui seront présentées comme une seule ligne Shell par le Shell.

Par exemple, la commande

git log --tags --branches HEAD FETCH_HEAD ORIG_HEAD --graph --decorate --pretty=oneline --simplify-by-decoration

peut s'écrire comme suit

git log --tags --branches HEAD FETCH_HEAD ORIG_HEAD \
    --graph --decorate --pretty=oneline --simplify-by-decoration

1voto

CODE-REaD Points 415

Avertissement : La barre oblique inversée ne continue une ligne que si elle est le tout dernier caractère de la ligne.

Cet article est quelque peu hors sujet ; je l'ajoute ici en tant qu'arrêt de spectacle facilement négligé. Si vous terminez par inadvertance une ligne dans votre Shell Shell avec \ (barre oblique inversée suivie d'un espace ou d'une tabulation) au lieu de \ vous pouvez constater que votre script cesse de s'exécuter ou se comporte de manière inattendue, même si les backslashs semble être le dernier caractère.

Si vous effectuez un montage avec vi il est facile de repérer ce problème avec la commande :set list qui placera un $ à la fin de chaque ligne, ce qui vous permettra de repérer les espaces ou les tabulations de fin de ligne. :set nolist désactive cette fonctionnalité de vi.

0voto

JezC Points 560
A=B\
C

signifie "A est égal à la chaîne B, suivie d'une nouvelle ligne que j'ignore, suivie d'un C".

Il n'y a pas de CR dans ce que vous avez tapé, pour autant que le Shell le voit. La fin de ligne de Linux/Unix est un saut de ligne (LF), pas un CR. Le CR est émis dans le cadre de la gestion du terminal. La plupart des terminaux ont besoin d'un saut de ligne pour sauter une ligne, et d'un retour chariot pour renvoyer le curseur vers la gauche. Le CR est inséré par le noyau, lors de l'envoi d'un Line Feed au terminal, lorsque le terminal en a besoin - c'est-à-dire qu'il n'est pas visible pour le Shell. Notez que, par exemple, un éditeur visuel pourrait séparer l'utilisation du CR et du LF - le moins de caractères vers le prochain morceau d'écran à réécrire peut très bien impliquer un LF (pour aller directement vers le bas de la page sans changer de colonne).

Un peu plus déroutant, il existe également une traduction de l'entrée pour les claviers. La touche Entrée envoie généralement un retour chariot (Control-M). Mais pour reconnaître qu'une commande a été saisie, le Shell doit voir une Fin de ligne. Un élément supplémentaire stty indique donc au traitement du terminal du noyau qu'une entrée CR doit être traduite en une fin de ligne. Ainsi, le Shell toujours ne voit pas de CR.

Le résultat final est que le terminal envoie :

A=B\<CR>C<CR>

Le Shell reçoit :

A=B\<LF>C<LF>

Le Shell analyse cela comme "oh, backslash newline - je l'ignore" et se retrouve avec :

A=BC<LF>

Et en sortie, le noyau modifie la séquence envoyée au terminal lors de l'entrée de la commande comme :

A=B\<CR><LF>C<CR><LF>

Le traitement par le noyau de la gestion des terminaux est géré par la commande Shell. stty et en fonction de l'implémentation (Linux, Mac OS X, *BSD), les détails sous-jacents devraient être sous man termios , man tty_ioctl . man console_ioctl etc.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X