echo znak nowej linii nie działa w bash


13

Mam skrypt bash, który ma wiele echoinstrukcji, a także alias echodo echo -eobu w .bash_profilei .bashrc, dzięki czemu nowe wiersze są drukowane poprawnie dla instrukcji takich jak echo 'Hello\nWorld'wynik powinien być

Hello
World

ale otrzymuję wynik

Hello\nWorld

Próbowałem nawet użyć shopt -s expand_aliasesw skrypcie, to nie pomaga

Uruchamiam skrypt jako bash /scripts/scriptnm.sh; jeśli uruchomię go, gdy . /scripts/scriptnm.shotrzymuję pożądaną wydajność ...


3
aliasing, echojak chcesz, to zła praktyka IMHO
shellholic

1
Użyj podwójnych cudzysłowów, aby \ n został zinterpretowany. Pojedyncze cudzysłowy uniemożliwiają interpretację \ n i wielu innych rzeczy.
BillThor,

Odpowiedzi:


16

Mieszana historia echooznacza, że ​​jej domyślne działanie różni się w zależności od powłoki. POSIX określa, że wynikiem echojest „zdefiniowany w implementacji”, jeśli pierwszym argumentem jest -nlub dowolny argument zawiera odwrotny ukośnik.

Bardziej niezawodne jest użycie printf(jako polecenia wbudowanego lub polecenia zewnętrznego), gdzie zachowanie jest lepiej zdefiniowane: znaki odwrotnego ukośnika w stylu C i specyfikatory formatu są obsługiwane w ciągu formatu (pierwszy argument).

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

Można kontrolować ekspansję BACKSLASH sekwencje z bash „s echowbudowane polecenie z xpg_echoopcją powłoki.

Ustaw go u góry dowolnego skryptu bash, aby echoautomatycznie rozszerzać sekwencje specjalne odwrotnego ukośnika bez konieczności dodawania -edo każdego polecenia echa.

shopt -s xpg_echo
echo 'foo\nbar'

shopt -s xpg_echo; Pracował dla mnie.
Bashuser

6

Gdy używasz bash myfile.sh, Bash jest uruchamiany w trybie „wsadowym”, w osobnym procesie i nie odczytuje swojego profilu ani pliku rc.

Kiedy używasz . myfile.sh, plik jest pobierany przez bieżący proces powłoki (tak jakby jego zawartość została przez Ciebie wpisana), dlatego widzi twoje aktualnie zdefiniowane aliasy.

Zasadniczo pisanie skryptów zależnych od konkretnej konfiguracji powłoki, zwłaszcza aliasów, jest bardzo złym pomysłem , chyba że zdefiniujesz je w samym skrypcie . ( Nigdy nie polegaj na użytkowniku .bashrc, nawet jeśli jest on Twój).


5

Zalecaną praktyką jest stosowanie printfwszystkich nowych skryptów.

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

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

+1 printf jest nieco bardziej skomplikowany w użyciu niż echo, ale bardziej niż opłaca się unikać niespójności echa.
Gordon Davisson,

1

Działa to dobrze w terminalu

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

zapisz do pliku i uczyń go wykonalnym (chmod + x)

uruchom jako ./twoj_plik


uruchom go jako bash twój_plik i sprawdź dane wyjściowe.
Bashuser,

Działa zgodnie z oczekiwaniami
LaLeX

ale echo „Hello \ nWorld” nie wyświetla oczekiwanego wyniku. Ponieważ echo jest już aliasowane do echa -e powinno, ale to nie działa i to jest moje pytanie
Bashuser

Ponieważ złą praktyką jest używanie echa aliasu (programy, które od niego zależą mogą się zepsuć), powinieneś usunąć alias iw swoim skrypcie szukać końca echa zastąpić go echo -e
LaLeX 11.11

Wielkie dzięki LaLex za twoje odpowiedzi, czy jest sposób, w jaki mogę osiągnąć oczekiwany wynik z aliasem, chociaż nie jest to dobra praktyka
Bashuser
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.