Почему только первая строка оценивается с помощью IFS=' '

Я пытаюсь разбить многострочную строку только на пробелы, сохраняя разрывы строк:

IFS=' ' read a b c <<< "$(printf '%s\n' "foo" "bar" "baz")"; echo "a=[$a]"; echo "b=[$b]"; echo "c=[$c]"

Ожидается:

a=[foo
bar
baz
]
b=[]
c=[]

Факт:

a=[foo]
b=[]
c=[]

Что мне не хватает? Когда я заменяю \n на \t, все работает как положено.

Я использую bash v5.0.18


person Rolf W.    schedule 25.10.2020    source источник
comment
Назначение в той же строке, что и команда (без разделителя, такого как ; между ними), применяется только к этой одной команде (и экспортирует переменную в среду во время выполнения этой одной команды, но не использует расширение оболочки на других этапах для этого команда).   -  person Charles Duffy    schedule 25.10.2020
comment
Другая важная — критическая — вещь заключается в том, что вы не передаете -d своему read. При чтении используются два разных разделителя: IFS определяет границу между словами в поле ввода; -d определяет границу между входами.   -  person Charles Duffy    schedule 25.10.2020
comment
... сделайте его IFS=' ' read -r -d '' a b c, и вы получите ожидаемое поведение. См. демонстрацию на странице ideone.com/g2hpuS.   -  person Charles Duffy    schedule 25.10.2020
comment
Спасибо, я не знал об этом нюансе команды чтения. У меня остается одна небольшая проблема, когда я использую флаг -d '', который заключается в том, что он завершается с ошибкой 1, потому что в конце ввода нет эквивалента новой строки: ideone.com/l6hL5B (сейчас я читаю в массив, но то же самое происходит с отдельными переменными). Поскольку предлагаемый разделитель — это пустая строка, и я думаю, что не могу добавить ее в конец, какую безопасную альтернативу вы бы предложили для успешного завершения чтения?   -  person Rolf W.    schedule 27.10.2020
comment
Обычная практика — read -r -d '' a || [[ $a ]], поэтому у вас есть составная команда, которая возвращает true, если целевая переменная была успешно заполнена.   -  person Charles Duffy    schedule 27.10.2020
comment
Кстати, -d '' относится к NUL (строки C заканчиваются NUL, первый и единственный символ пустой строки — NUL). Вы можете излучать их с помощью printf '\0'.   -  person Charles Duffy    schedule 27.10.2020