Разница между echo -e «<string>» и echo $ «<string>»

20

Какова разница между использованием

echo -e "Hello\nWorld" 

и

echo $"Hello\nWorld" 

разве они оба не выводят:

Hello
World
отметка
источник
1
Вы пробовали это? Второй вывод Hello\nWorld. Вам нужен -eпереключатель для интерпретации escape-символов.
becko
4
Во-вторых, я подозреваю, что вы хотели написать это в одинарных кавычках echo $'Hello\nWorld', которые будут напечатаны в двух строках под bash.
Джон1024
@becko, да, я попробовал, и они оба выдают одну и ту же вещь.
Mark

Ответы:

33

echo -eи echo $'...'оба похожи в том, что они поддерживают следующие escape-последовательности:

  \a     alert (bell)
  \b     backspace
  \e
  \E     an escape character
  \f     form feed
  \n     new line
  \r     carriage return
  \t     horizontal tab
  \v     vertical tab
  \\     backslash
  \0nnn  the eight-bit character whose value is the octal value nnn (zero to three octal digits)
  \xHH   the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
  \uHHHH the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)
  \UHHHHHHHH
         the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits)

У них есть различия. В дополнение к вышесказанному, echo -eподдерживает:

  \c     suppress further output
  \0nnn  the eight-bit character whose value is the octal value nnn (zero to three octal digits)

Напротив, $'....'поддерживает:

 \'     single quote
 \"     double quote
 \nnn   the eight-bit character whose value is the octal value nnn (one to three digits)
 \cx    a control-x character

Заметьте, что между ними \cрасширения несовместимы:

$ echo -e  'start\n\cIstop'
start
$ echo  $'start\n\cIstop'
start
        stop

Для echo -eвыше, \cподавляет дальнейший вывод, тем самым игнорируя Istop. Напротив, для $'...', \cIинтерпретируется как вкладка.

Визуально-подобная форма: $"..."

В отличие от $'...', функция $"..."совершенно иная. Это приведет к переводу содержащейся строки в соответствии с текущей локалью.

echo -eспоры

echo -eне всегда поддерживается оболочками, и многие считают эту -eопцию ошибкой проекта. Заметим:

$ ls
-e  -n
$ echo *
$ printf "%s\n" *
-e
-n

Как вы можете видеть, если то, что вы печатаете, echoначинается с тире, результаты могут быть неожиданными. Если вы не уверены, что первая строка, с которой вы будете печатать echo, не начинается с тире, вам, вероятно, лучше использовать printf.

По этим причинам стандарт POSIX заключает :

В новых приложениях рекомендуется использовать printf вместо echo.

Чет Рами, который поддерживал в bashтечение прошлых 22 лет, соглашается :

[N] Новый код должен использовать printf.

John1024
источник
1
Также стоит отметить, что и Chet, и POSIX рекомендуют использовать, printfа неecho
geirha
@geirha Очень хорошие моменты. Ответ обновлен.
John1024
1
Проблема неожиданных опций от globs (вроде *) на самом деле не является специфической echo. Это происходит с любой командой, которая распознает короткие или длинные опции (записанные традиционным способом) и принимает операнды имени файла, включаяls . Возможно, ситуация немного хуже, echoпоскольку (как упоминает ваш источник) echoобычно не принимает --указание окончания опций, в то время как можно писать такие команды, как ls -- *l. (И действительно, обычно следует писать команды таким образом, когда используются глобусы, начинающиеся с *или -, особенно в сценариях.)
Элия ​​Каган
Спасибо за обстоятельный ответ, у меня есть для моих пребывания Операционных систем , конечно , и мне нужно , чтобы распечатать текст с помощью \nпоследовательности символов, так что на самом деле это не имеет значения , если я использую echo -e '...', echo $'...'илиecho $"..."
Mark