Перевод строки удаляется из эха при вызове в двойных кавычках

Я пытаюсь заполнить переменную оболочки с именем $recipient, которая должна содержать значение, за которым следует новая строка.

$ set -x # force bash to show commands as it executes them

Я начинаю с заполнения $user — значения, за которым должен следовать перевод строки.

$ [email protected]
+ [email protected]

Затем я вызываю echo $user внутри подстановки команд в двойных кавычках. Оператор echo должен создавать новую строку после $user, а двойные кавычки должны сохранять новую строку.

$ recipient="$(echo $user)"
++ echo [email protected]
+ [email protected]

Однако, когда я печатаю $recipient, я вижу, что новая строка была отброшена.

$ echo "'recipient'"
+ echo ''\''recipient'\'''
'recipient'

Я обнаружил такое же поведение в версиях bash 4.1.5 и 3.1.17, а также воспроизвел проблему в dash.

Я попытался использовать «printf», а не эхо; это ничего не изменило.

Это ожидаемое поведение?


person Barton Chittenden    schedule 09.01.2013    source источник


Ответы (2)


Подстановка команд удаляет завершающие символы новой строки. Из стандарта:

Оболочка должна расширить подстановку команд, выполнив команду в среде подоболочки (см. Среда выполнения оболочки) и заменив подстановку команды (текст команды плюс закрывающий «$()» или обратные кавычки) стандартным выводом команды, удалив последовательности из одного или нескольких символов в конце замены. Встроенные символы перед концом вывода не удаляются; однако они могут рассматриваться как разделители полей и исключаться при разделении полей, в зависимости от значения IFS и действующих кавычек. Если выходные данные содержат нулевые байты, поведение не указано.

Вам нужно будет явно добавить новую строку. Возможно:

recipient="$user
"

Здесь действительно нет причин использовать подстановку команд. (Иными словами, $(echo ...) почти всегда глупо делать.)

person William Pursell    schedule 09.01.2013

Все версии оболочки будут реагировать одинаково, в написании сценариев нет ничего нового.

Новая строка в конце исходного задания не включается в значение переменной. Он только «завершает» текущий cmd и сигнализирует оболочке о необходимости обработки.

Возможно, user="[email protected]\n" будет работать, но без контекста о том, почему вы этого хотите, просто знайте, что люди обычно хранят значения переменных отдельно от "инструментов" форматирования, таких как новая строка.

ИХТХ.

person shellter    schedule 09.01.2013