echo newline character not working in bash

13

J'ai un script bash qui a beaucoup d' echoinstructions et j'ai également un alias echoà la echo -efois dans .bash_profileet .bashrc, afin que les nouvelles lignes soient imprimées correctement pour une instruction comme echo 'Hello\nWorld'la sortie devrait être

Hello
World

mais la sortie que je reçois est

Hello\nWorld

J'ai même essayé d'utiliser shopt -s expand_aliasesdans le script, ça n'aide pas

J'exécute mon script en tant que bash /scripts/scriptnm.sh; si je l'exécute car . /scripts/scriptnm.shj'obtiens la sortie souhaitée ...

Bashuser
la source
3
aliasing echocomme vous voulez est une mauvaise pratique à
mon humble avis
1
Utilisez des guillemets doubles pour que le \ n soit interprété. Les guillemets simples empêchent l'interprétation de la \ n et un tas d'autres choses.
BillThor

Réponses:

16

L'histoire mixte de echosignifie que son fonctionnement par défaut varie d'un shell à l'autre. POSIX spécifie que le résultat de echoest «défini par l'implémentation» si le premier argument est -nou si n'importe quel argument contient une barre oblique inverse.

Il est plus fiable à utiliser printf(soit comme une commande intégrée soit comme une commande externe) où le comportement est mieux défini: la barre oblique inversée de style C et les spécificateurs de format sont pris en charge dans la chaîne de format (le premier argument).

printf 'foo\nbar\n'
printf '%s\n%s\n' foo bar

Vous pouvez contrôler l'expansion des séquences d'échappement backslash de bash est echocommande intégrée avec l' xpg_echooption shell.

Placez-le en haut de n'importe quel script bash pour echodévelopper automatiquement les échappements de barre oblique inverse sans avoir à ajouter -eà chaque commande echo.

shopt -s xpg_echo
echo 'foo\nbar'
Chris Johnsen
la source
shopt -s xpg_echo; A travaillé pour moi.
Bashuser
6

Lorsque vous utilisez bash myfile.sh, Bash est exécuté en mode "batch", sur un processus distinct , et ne lit pas son profil ou son fichier rc.

Lorsque vous utilisez . myfile.sh, le fichier provient du processus shell actuel (comme si son contenu avait été tapé par vous), il voit donc vos alias actuellement définis.

En général, c'est une très mauvaise idée d'écrire des scripts qui dépendent d'une configuration particulière du shell, en particulier des alias, sauf si vous les définissez dans le script lui-même. ( Ne comptez jamais sur l'utilisateur .bashrc, même s'il est le vôtre.)

user1686
la source
5

La pratique recommandée consiste à utiliser printfpour tous les nouveaux scripts.

printf '%s\n%s\n' "Hello" "World"

printf '%s\n' "Hello\nWorld"
En pause jusqu'à nouvel ordre.
la source
+1 printf est un peu plus compliqué à utiliser que l'écho, mais il vaut mieux que d'éviter les incohérences de l'écho.
Gordon Davisson
1

Cela fonctionne bien dans le terminal

#!/bin/bash
alias echo="echo -e"
echo "Hello\nWorld"

enregistrer dans un fichier et le rendre utilisable (chmod + x)

exécuter en tant que ./votre_fichier

LaLeX
la source
exécutez-le comme bash your_file et vérifiez la sortie.
Bashuser
Fonctionne comme prévu
LaLeX
mais l'écho "Hello \ nWorld" n'affiche pas la sortie attendue. Comme echo est déjà un alias pour echo -e il devrait mais cela ne fonctionne pas et c'est ma question
Bashuser
Comme il est mauvais d'alias echo (les programmes qui en dépendent peuvent se casser), vous devez supprimer l'alias et dans votre recherche de script pour echo end le remplacer par echo -e
LaLeX
Merci beaucoup LaLex pour vos réponses, existe-t-il un moyen pour que j'obtienne le résultat escompté avec l'alias bien que ce ne soit pas une bonne pratique
Bashuser