Jak już wspomniano, bardziej przenośnym sposobem użycia zmiennej jest zacytowanie jej:
$ 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$
Istnieje różnica w implementacji w bash, z linią:
l="$(printf '%s\t%s\t%s\n' foo bar baz)"; <<<$l sed -n l
Jest to wynik większości powłok:
/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$
Tylko bash dzieli zmienną po prawej stronie, <<<
gdy nie jest cytowany.
Zostało to jednak poprawione w wersji bash 4.4.
Oznacza to, że wartość parametru $IFS
wpływa na wynik <<<
.
Z linią:
l=(1 2 3); IFS=:; sed -n l <<<"${l[*]}"
Wszystkie powłoki używają pierwszego znaku IFS do łączenia wartości.
/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$
W "${l[@]}"
przypadku oddzielenia różnych argumentów potrzebna jest spacja, ale niektóre powłoki wybierają wartość z IFS (czy to prawda?).
/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$
Przy zerowym IFS wartości powinny zostać połączone, podobnie jak w tym wierszu:
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$
Ale zarówno lksh, jak i mksh tego nie robią.
Jeśli przejdziemy do listy argumentów:
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$
Zarówno yash, jak i zsh nie rozdzielają argumentów. Czy to błąd?
echo -e 'foo\tbar\tbaz\n...'
,echo $'foo\tbar\tbaz\n...'
lubprintf 'foo\tbar\tbaz\n...\n'
lub odmiany tych. Pozwala to uniknąć konieczności indywidualnego zawijania każdej karty lub nowej linii.