Почему bash here-string добавляет завершающий символ новой строки?


34

Следующие примеры показывают, что новая строка добавляется в строку here .
Почему это сделано?

xxd -p <<<'a'  
# output: 610a

xxd -p <<<'a
'
# output: 610a0a

Ответы:


38

Простой ответ заключается в том, что ksh написан именно так (а bash совместим). Но есть причина такого выбора дизайна.

Большинство команд ожидают ввода текста. В мире Unix текстовый файл состоит из последовательности строк, каждая из которых заканчивается новой строкой . Так что в большинстве случаев требуется заключительный перевод строки. Особенно распространенным случаем является получение выходных данных команды с помощью команды susbtitution, ее обработка каким-либо образом, а затем передача другой команде. Подстановка команд удаляет последние символы новой строки; <<<ставит один обратно.

tmp=$(foo)
tmp=${tmp//hello/world}
tmp=${tmp#prefix}
bar <<<$tmp

Bash и ksh не могут манипулировать двоичными данными в любом случае (они не справляются с нулевыми символами), поэтому неудивительно, что их средства ориентированы на текстовые данные.

<<<Синтаксис здесь строка в основном только для удобства в любом случае, как <<здесь-документов. Если вам не нужно добавлять заключительный перевод строки, используйте echo -n(в bash) или printfи конвейер.


Гораздо тщательнее, чем мой ответ.
Майк

2
Bash, возможно, позаимствовал здесь строки из ksh93, но ksh, в свою очередь, позаимствовал их у zsh, который получил их из оболочки Plan 9 rc .
Марк Рид

2
<<<был представлен миру Борна zsh, нет ksh. И это было вдохновлено аналогичным оператором в порту Unix, rcкоторый не добавил этот дополнительный символ новой строки. Интересно, что =(<<<text)оператор не добавляет эту новую строку в zsh.
Стефан Шазелас

Если вам интересно, интерес к этому ответу из-за этого вопроса в SO .
Федорки

1
Есть ли способ написать здесь-строку (без использования какой-либо другой утилиты, такой как printf, и т. Д.), Избегая хвостовой строки bash? Как @ StéphaneChazelas указал, возможно в zsh.
CTodea

3

Один сценарий, в котором целесообразно добавлять символы новой строки к строкам здесь, - это использование readкоманды, когда set -eактивен режим. Напомним, что set -eсценарий завершается, когда он (более или менее) встречает операторы, которые генерируют ненулевой код состояния. Предположим, что readгенерируется ненулевой код состояния, когда он встречает строку без перевода строки:

#!/bin/bash
set -e

# The following statement succeeds because here-strings append a newline:
IFS='' read -r <<< 'newline appended'
echo 'Made it here'

# The following statement fails because 'read' returns a non-zero status
# code when no newlines are encountered.
printf 'no newline' | IFS='' read -r
echo 'Did not make it here'

-3

Я думаю, что это единственный способ получить новую строку в конце строки, доказательство:

xxd <<<`echo -ne "a\n"`

Может показаться, что оператор here-string удаляет символы новой строки, если они не указаны в предоставленном вами синтаксисе.


4
Это замена команды, которая удаляет последний перевод строки. Вы могли бы упростить это до xxd <<<$(echo a).
Жиль "ТАК - перестань быть злым"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.