Чому команди "echo -e", схоже, не дають правильного результату?


21

У терміналі Ubuntu 18.04 LTS, коли я записую цю команду:

echo -e "Hello\\\n"

Це дає це як вихід:

Hello\n

Але він повинен бути надрукований, як мовиться на сторінці man :

Hello\

Тобто спочатку друк Hello, потім \, потім символ нового рядка (а потім ще один новий рядок). Де проблема?

Дивіться ці кілька echo -eкоманд та їх вихід :

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

так.для першого 2 \ він повинен вивести \ .і останній \ і n зробити зворотну косу рису \ n (новий рядок). Тому чому він повинен надрукувати Hello \
yolin00

1
Спробуйте без лапок.
ajgringo619

2
Дивовижну відповідь надав Елія Каган, яку ви повинні прийняти.
ванадій

2
Не використовуйте echoв першу чергу: використовуйте printf.
чепнер

2
Завжди використовуйте одинарні лапки, якщо хочете бути впевненими, що те, що ви пишете, саме те, що передається команді як аргумент.
Джакомо Альзетта

Відповіді:


29

Резервні боки обробляються спеціально echo -e, але спочатку вони інколи обробляються спеціально шкаралупою (що в даному випадку є bash), відповідно до правил котирування оболонки .

Аргумент echoнасправді бачить, є Hello\\n. Оскільки ви перейшли -eдо цього echo, він обробляє втечу зворотної косої риси спеціально і \\згортається до єдиного \. Фіналу nне уникнути, тому він постає буквально.

Причиною цього є те, що до та окремо від самої роботи echoоболонка розглядає \спеціально в деяких контекстах, але не в інших. Некотируваних \символи завжди розглядаються спеціально, в одинарних лапках \ , ніколи не розглядаються спеціально, але лікування в подвійних лапках \ символів, як в команді ви запускали, є більш тонким і складним.

Коли оболонка стикається з текстом із подвійним цитуванням у команді, як і у випадку "Hello\\\n", вона розглядає \як символ втечі, коли вона передує символу, який може мати особливе значення всередині подвійних лапок, а не інакше .

  1. Оскільки \іноді має особливе значення всередині "", \те, що негайно передує іншому \, спричиняє цитування цієї секунди \. Тож всередині подвійних лапок перші \\потрапляють у \.
  2. Після цих перших двох \символів з’являється третій \символ, на який не впливають перші два, який передує n. Але nце не персонаж, до якого коли-небудь звертаються спеціально всередині подвійних цитат, тому \до цього не звертаються спеціально в цій ситуації. Таким чином \nзалишається \n.

Ефект полягає в тому, що в подвійних лапках \\\nтрактується як \\n.

Коли echo -eбачить \\n, перший \видаляє спеціальне значення з другого, тому echoдрукується \nбуквально для цього тексту.


Якщо ваша мета - надрукувати Helloдодатковий новий рядок, але без зворотних нахилів (питання спочатку було неоднозначним, плюс я думаю, що це корисний приклад), тоді одне рішення - видалити \. Запуск echo -e "Hello\\n"результатів Helloз додатковою новою лінією в кінці.

Кращим рішенням є використання одиничних лапок і написання echo -e 'Hello\n'. Одиночні котирування є найсильнішою формою цитування. Ще кращим рішенням є використання printfзамість того echo, що в цьому випадку було б printf 'Hello\n\n'.

Якщо ваша мета - друкувати, Hello\включаючи зворотний проріз, з подальшим додатковим новим рядком , то підхід з подвійним цитуванням можливий, але громіздкий. Щоб зрозуміти це, працювати в зворотному напрямку: echo -eзвернених \\до \і \nв символ нового рядка, і подвійні лапки звернених \\до \, так що ви можете зробити це з шістьма слеш ( echo -e "Hello\\\\\\n"), так як \\nперетворюється \nз - за однієї зворотної косої межі втечі інший. Ви також можете зробити це з п'ятьма, оскільки подвійне цитування зберігається, \nколи значення \не уникне.

Це ілюструє перевагу одного цитування: просто поставте все, що ви хочете echo -eпобачити, в одній цитаті ( echo -e 'Hello\\\n'). printfтут також добре. Один варіант є printf 'Hello\\\n\n'. Але де printfсправді світить, це те, що ви можете підключити додаткові аргументи. Ви можете використовувати printf '%s\n\n' 'Hello\', який вставляє другий аргумент (буквально Hello\тому, що окремі цитати нічого не змінюють) замість %s.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.