Як уже було сказано, більш портативним способом використання змінної є цитування її:
$ printf '%s\t%s\t%s\n' foo bar baz
foo bar baz
$ l="$(printf '%s\t%s\t%s\n' foo bar baz)"
$ <<<$l sed -n l
foo bar baz$
$ <<<"$l" sed -n l
foo\tbar\tbaz$
Існує різниця в реалізації в bash, з рядком:
l="$(printf '%s\t%s\t%s\n' foo bar baz)"; <<<$l sed -n l
Це результат більшості снарядів:
/bin/sh : foo bar baz$
/bin/b43sh : foo bar baz$
/bin/bash : foo bar baz$
/bin/b44sh : foo\tbar\tbaz$
/bin/y2sh : foo\tbar\tbaz$
/bin/ksh : foo\tbar\tbaz$
/bin/ksh93 : foo\tbar\tbaz$
/bin/lksh : foo\tbar\tbaz$
/bin/mksh : foo\tbar\tbaz$
/bin/mksh-static: foo\tbar\tbaz$
/usr/bin/ksh : foo\tbar\tbaz$
/bin/zsh : foo\tbar\tbaz$
/bin/zsh4 : foo\tbar\tbaz$
Тільки bash розділяє змінну праворуч від <<<
котирування.
Однак це було виправлено у версії 4.4 bash.
Це означає, що значення $IFS
впливає на результат <<<
.
За допомогою рядка:
l=(1 2 3); IFS=:; sed -n l <<<"${l[*]}"
Усі оболонки використовують перший символ IFS для приєднання значень.
/bin/y2sh : 1:2:3$
/bin/sh : 1:2:3$
/bin/b43sh : 1:2:3$
/bin/b44sh : 1:2:3$
/bin/bash : 1:2:3$
/bin/ksh : 1:2:3$
/bin/ksh93 : 1:2:3$
/bin/lksh : 1:2:3$
/bin/mksh : 1:2:3$
/bin/zsh : 1:2:3$
/bin/zsh4 : 1:2:3$
З "${l[@]}"
, потрібний пробіл для розділення різних аргументів, але деякі оболонки вирішують використовувати значення з IFS (чи правильно це?).
/bin/y2sh : 1:2:3$
/bin/sh : 1 2 3$
/bin/b43sh : 1 2 3$
/bin/b44sh : 1 2 3$
/bin/bash : 1 2 3$
/bin/ksh : 1 2 3$
/bin/ksh93 : 1 2 3$
/bin/lksh : 1:2:3$
/bin/mksh : 1:2:3$
/bin/zsh : 1:2:3$
/bin/zsh4 : 1:2:3$
З нульовим IFS значення повинні стати об'єднаними, як у цьому рядку:
a=(1 2 3); IFS=''; sed -n l <<<"${a[*]}"
/bin/y2sh : 123$
/bin/sh : 123$
/bin/b43sh : 123$
/bin/b44sh : 123$
/bin/bash : 123$
/bin/ksh : 123$
/bin/ksh93 : 123$
/bin/lksh : 1 2 3$
/bin/mksh : 1 2 3$
/bin/zsh : 123$
/bin/zsh4 : 123$
Але і lksh, і mksh цього не вдається.
Якщо ми переходимо до списку аргументів:
l=(1 2 3); IFS=''; sed -n l <<<"${l[@]}"
/bin/y2sh : 123$
/bin/sh : 1 2 3$
/bin/b43sh : 1 2 3$
/bin/b44sh : 1 2 3$
/bin/bash : 1 2 3$
/bin/ksh : 1 2 3$
/bin/ksh93 : 1 2 3$
/bin/lksh : 1 2 3$
/bin/mksh : 1 2 3$
/bin/zsh : 123$
/bin/zsh4 : 123$
І yash, і zsh не вдається розділити аргументи. Це помилка?
echo -e 'foo\tbar\tbaz\n...'
,echo $'foo\tbar\tbaz\n...'
або ,printf 'foo\tbar\tbaz\n...\n'
або варіації цих. Це позбавить вас від необхідності індивідуально перегортати кожну вкладку чи новий рядок.