bash read -d '' 的作用是什么?
What does the bash read -d '' do?
-d ''
在 bash 读取命令中的作用是什么?该示例直接来自 a previous SO。从 read 命令打印的用法来看,它说 -d
选项定义了一行中用于拆分单词的分隔符。空分隔符有什么作用?
read -d '' sql << EOF
select c1, c2 from foo
where c1='something'
EOF
echo "$sql"
我通过实验知道用它为变量分配了多行。没有它,只会分配第一行。似乎很难根据用法文本来解释这种行为。
In bash read
内置空字符串分隔符 -d ''
与使用分隔符作为 NUL 字节或 $'[=14=]'
的行为相同(由 ANSI C 引号字符串定义)或十六进制表示 0x0
.
-d ''
指定每个输入行应由 NUL 字节分隔。这意味着在每次调用 read
.
时,输入字符串被读取到紧邻的下一个 NUL 字符
通常与IFS=
一起使用:
IFS= read -r -d ''
用于修剪输入中的前导和尾随空格。
处理 NUL 分隔输入的常见示例是:
while IFS= read -r -d '' file; do
echo "$file"
done < <(find . -type f -print0)
find
命令正在打印当前目录中的文件,每个条目之间以 NUL 作为分隔符。
read -d ''
将 [=21=]
设置为分隔符,用于从 find
命令的输出中一次读取一个条目。
相关:
read -d
将停止读取的字符从默认换行符更改为以下参数的第一个字符。
要理解的重要一点是 bash 使用 C 字符串,这些字符串由文字 NUL 终止。因此,当后面的参数是 ''
时,第一个(也是唯一的)字符是终止它的 NUL;因此,当 shell 取消引用 char*
以获取它指向的第一个字符时,它会得到一个 NUL。
现在,当您使用 <<EOF
重定向 heredoc 时,该文档实际上不会包含任何 NUL -- 那么您的代码如何工作?
答案是您的代码预计read
操作会失败。即使失败,read
仍会填充其目标变量;所以如果你没有终止分隔符,read
有一个非零退出状态......但它仍然把你想要收集的所有数据无论如何都放在变量中!
对于不触发set -e
错误的版本,考虑读取完成后检查目标变量是否为空:
{ IFS= read -r -d '' string || [[ $string ]]; } <<'EOF'
...string goes here...
EOF
我们做了哪些改变?
IFS=
防止去除前导或尾随空格(或其他字符,如果 IFS 已重新定义)。
read -r
防止带有反斜杠文字的内容被破坏。
|| [[ $string ]]
表示如果 read
报告失败,我们将检查字符串是否已填充,如果变量不为空,则仍然认为整个命令成功。
-d ''
在 bash 读取命令中的作用是什么?该示例直接来自 a previous SO。从 read 命令打印的用法来看,它说 -d
选项定义了一行中用于拆分单词的分隔符。空分隔符有什么作用?
read -d '' sql << EOF
select c1, c2 from foo
where c1='something'
EOF
echo "$sql"
我通过实验知道用它为变量分配了多行。没有它,只会分配第一行。似乎很难根据用法文本来解释这种行为。
In bash read
内置空字符串分隔符 -d ''
与使用分隔符作为 NUL 字节或 $'[=14=]'
的行为相同(由 ANSI C 引号字符串定义)或十六进制表示 0x0
.
-d ''
指定每个输入行应由 NUL 字节分隔。这意味着在每次调用 read
.
通常与IFS=
一起使用:
IFS= read -r -d ''
用于修剪输入中的前导和尾随空格。
处理 NUL 分隔输入的常见示例是:
while IFS= read -r -d '' file; do
echo "$file"
done < <(find . -type f -print0)
find
命令正在打印当前目录中的文件,每个条目之间以 NUL 作为分隔符。read -d ''
将[=21=]
设置为分隔符,用于从find
命令的输出中一次读取一个条目。
相关:
read -d
将停止读取的字符从默认换行符更改为以下参数的第一个字符。
要理解的重要一点是 bash 使用 C 字符串,这些字符串由文字 NUL 终止。因此,当后面的参数是 ''
时,第一个(也是唯一的)字符是终止它的 NUL;因此,当 shell 取消引用 char*
以获取它指向的第一个字符时,它会得到一个 NUL。
现在,当您使用 <<EOF
重定向 heredoc 时,该文档实际上不会包含任何 NUL -- 那么您的代码如何工作?
答案是您的代码预计read
操作会失败。即使失败,read
仍会填充其目标变量;所以如果你没有终止分隔符,read
有一个非零退出状态......但它仍然把你想要收集的所有数据无论如何都放在变量中!
对于不触发set -e
错误的版本,考虑读取完成后检查目标变量是否为空:
{ IFS= read -r -d '' string || [[ $string ]]; } <<'EOF'
...string goes here...
EOF
我们做了哪些改变?
IFS=
防止去除前导或尾随空格(或其他字符,如果 IFS 已重新定义)。read -r
防止带有反斜杠文字的内容被破坏。|| [[ $string ]]
表示如果read
报告失败,我们将检查字符串是否已填充,如果变量不为空,则仍然认为整个命令成功。