W terminalu Ubuntu 18.04 LTS, kiedy piszę to polecenie:
echo -e "Hello\\\n"
Daje to jako wynik:
Hello\n
Ale to powinno wydrukować, ponieważ mężczyzna strona mówi:
Hello\
Oznacza to, że najpierw wydrukuj Hello
, a \
następnie znak nowej linii (a następnie kolejną nową linię). Gdzie jest problem?
Zobacz te kilka echo -e
poleceń i ich wyniki :
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
źródło
źródło
echo
przede wszystkim: używajprintf
.Odpowiedzi:
Odwrotne ukośniki są traktowane specjalnie przez
echo -e
, ale najpierw są one traktowane specjalnie przez powłokę (która w tym przypadku jestbash
), zgodnie z regułami cytowania powłoki .Argument
echo
faktycznie widzi toHello\\n
. Ponieważ minęło-e
sięecho
, traktuje Odwrotny ukośnik cytuje specjalnie, i\\
jest zwinięta do pojedynczej\
. Finałn
nie jest ucieczkowy, więc wydaje się dosłownie.Powodem tego jest to, że przed i niezależnie od samego działania
echo
, powłoka traktuje\
specjalnie w niektórych kontekstach, ale nie w innych. Nienotowane\
znaki są zawsze traktowane specjalnie, jedno-cytowany\
nigdy nie są traktowane specjalnie, ale leczenie podwójnie cytowany\
znaków, jak w poleceniu uruchomiono, jest bardziej subtelne i skomplikowane.Gdy powłoka napotyka tekst w cudzysłowie, podobnie jak w przypadku polecenia,
"Hello\\\n"
traktuje go\
jako znak zmiany znaczenia, gdy poprzedza znak, który może mieć specjalne znaczenie w cudzysłowach, a nie inaczej .\
czasami ma w środku specjalne znaczenie""
, to,\
co bezpośrednio poprzedza inne\
, powoduje zacytowanie tej sekundy\
. Wewnątrz podwójnych cudzysłowów pierwsze\\
są zwinięte\
.\
znakach pojawia się trzeci\
znak, na który nie wpływają pierwsze dwa znaki i który poprzedza znak ann
. Alen
nie jest postacią, która jest traktowana specjalnie wewnątrz podwójnych cudzysłowów, więc\
wcześniej nie jest traktowana specjalnie w tej sytuacji. Tak\n
zostaje\n
.Skutkuje to tym, że w podwójnych cudzysłowach
\\\n
jest interpretowany jako\\n
.Kiedy
echo -e
widzi\\n
, pierwszy\
usuwa specjalne znaczenie z drugiego, więcecho
drukuje\n
dosłownie dla tego tekstu.Jeśli Twoim celem jest wydrukowanie
Hello
z nowym znakiem nowej linii, ale bez ukośników odwrotnych (pytanie było pierwotnie dwuznaczne, a myślę, że jest to przydatny przykład), wówczas jednym z rozwiązań jest usunięcie znaku\
. Uruchamianieecho -e "Hello\\n"
wynikówHello
z dodatkową nową linią na końcu.Lepszym rozwiązaniem jest stosowanie pojedynczych cudzysłowów i pisanie
echo -e 'Hello\n'
. Pojedyncze cytaty to najsilniejsza forma cytowania. Jeszcze lepszym rozwiązaniem jest użycieprintf
zamiast tegoecho
, co w tym przypadku byłobyprintf 'Hello\n\n'
.Jeśli Twoim celem jest wydrukowanie z
Hello\
uwzględnieniem odwrotnego ukośnika, a następnie dodatkowego nowego wiersza , możliwe jest zastosowanie podwójnego cytowania, ale uciążliwe. Aby to zrozumieć, pracuj wstecz:echo -e
konwertuje\\
na\
i\n
do nowej linii, a podwójne cudzysłowy konwertuje\\
na\
, abyś mógł to zrobić za pomocą sześciu ukośników odwrotnych (echo -e "Hello\\\\\\n"
), ponieważ\\n
zmienia się w\n
skutek ucieczki jednego ukośnika odwrotnego. Możesz to również zrobić z pięcioma, ponieważ podwójne cytowanie zachowuje się,\n
gdy\
nie jest poprzedzane znakiem ucieczki.To ilustruje korzyść
echo -e
pojedynczego cudzysłowu : po prostu umieść wszystko, co chcesz zobaczyć w pojedynczym cudzysłowie (echo -e 'Hello\\\n'
).printf
tutaj też jest dobrze. Jedną z opcji jestprintf 'Hello\\\n\n'
. Aleprintf
naprawdę wyróżnia się to, że możesz podłączyć dodatkowe argumenty. Możesz użyćprintf '%s\n\n' 'Hello\'
, który wstawia drugi argument (dosłownie,Hello\
ponieważ pojedyncze cudzysłowy niczego nie zmieniają) zamiast%s
.źródło