Như đã được trả lời, một cách dễ sử dụng hơn để sử dụng một biến là trích dẫn nó:
$ 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$
Có một sự khác biệt của việc thực hiện trong bash, với dòng:
l="$(printf '%s\t%s\t%s\n' foo bar baz)"; <<<$l sed -n l
Đây là kết quả của hầu hết các shell:
/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$
Chỉ bash phân chia biến ở bên phải <<<
khi không được trích dẫn.
Tuy nhiên, điều đó đã được sửa trên bash phiên bản 4.4
Điều đó có nghĩa là giá trị $IFS
ảnh hưởng đến kết quả của <<<
.
Với dòng:
l=(1 2 3); IFS=:; sed -n l <<<"${l[*]}"
Tất cả các shell sử dụng ký tự đầu tiên của IFS để nối các giá trị.
/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$
Với "${l[@]}"
, một khoảng trắng là cần thiết để phân tách các đối số khác nhau, nhưng một số shell chọn sử dụng giá trị từ IFS (Điều đó có đúng không?).
/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$
Với IFS null, các giá trị sẽ được nối, như với dòng này:
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$
Nhưng cả lksh và mksh đều không làm như vậy.
Nếu chúng ta thay đổi thành một danh sách các đối số:
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$
Cả yash và zsh đều không giữ các đối số tách biệt. Đó có phải là một lỗi không?
echo -e 'foo\tbar\tbaz\n...'
,echo $'foo\tbar\tbaz\n...'
, hoặcprintf 'foo\tbar\tbaz\n...\n'
hoặc các biến thể trong số này. Nó giúp bạn không phải bọc riêng từng tab hoặc dòng mới.