Чому баш тут-рядка додає проміжний знак нового рядка?


34

Наступні приклади показують, що новий рядок додається до рядка тут .
Чому це робиться?

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

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

Відповіді:


38

Відповідь проста, тому що ksh написано саме так (і bash сумісний). Але є вибір такого дизайну.

Більшість команд очікують введення тексту. У світі Unix текстовий файл складається з послідовності рядків, кожен з яких закінчується новим рядком . Тому в більшості випадків потрібна остаточна нова лінія. Особливо поширений випадок - це схопити вихід команди з підпорядкуванням команди, обробити його певним чином, а потім передати його іншій команді. Заміна команди знімає заключні нові рядки; <<<кладе одну спину.

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

Bash і ksh ніяк не можуть маніпулювати бінарними даними (він не справляється з нульовими символами), тому не дивно, що їх засоби орієнтовані на текстові дані.

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


Набагато ретельніше, ніж моя відповідь.
Майк

2
Bash, можливо, запозичив тут-рядки з ksh93, але ksh у свою чергу запозичив їх у zsh, який отримав їх із оболонки RC 9 .
Марк Рід

2
<<<був внесений у світ Борна zsh, ні ksh. І це надихнуло аналогічного оператора, який знаходиться в порту Unix, rcякий не додав додаткового символу нового рядка. Цікаво, що =(<<<text)оператор не додає цей новий рядок у zsh.
Стефан Шазелас

Якщо ви замислюєтесь про зацікавленість у цій відповіді, саме через це питання в ТА .
fedorqui

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"`

Здається, що оператор тут-рядка знімає нові рядки, якщо вони не вказані у представленому вами синтаксисі.


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