首页 > 解决方案 > bash read -d '' 有什么作用?

问题描述

bash 读取命令中的 a有什么作用-d ''?该示例直接来自以前的 SO。从 read 命令打印的用法来看,该-d选项定义了用于在一行中分割单词的分隔符。空分隔符有什么作用?

read -d '' sql << EOF
select c1, c2 from foo
where c1='something'
EOF

echo "$sql"

我通过试验知道变量被分配了多行。没有它,只分配第一行。根据用法文本似乎很难解释这种行为。

标签: bashdelimiterreadline

解决方案


read -d将停止读取的字符从默认换行符更改为以下参数的第一个字符。

要理解的重要一点是 bash 使用 C 字符串,这些字符串由文字 NUL 终止。因此,当以下参数为 时'',第一个(也是唯一一个)字符是终止它的 NUL;因此,当 shell 取消引用char*以获取它指向的第一个字符时,它会得到一个 NUL。


现在,当您使用 重定向heredoc 时<<EOF,该文档中实际上不会包含任何NUL——那么您的代码是如何工作的呢?

答案是您的代码期望read操作失败。即使失败,read仍会填充其目标变量;因此,如果您没有终止分隔符,read则退出状态为非零......但无论如何它仍然会将您想要收集的所有数据放入变量中!

对于不触发set -e错误的版本,请考虑在读取完成后检查目标变量是否为空:

{ IFS= read -r -d '' string || [[ $string ]]; } <<'EOF'
...string goes here...
EOF

我们做了哪些改变?

  • IFS=防止前导或尾随空格(或其他字符,如果 IFS 已被重新定义)被剥离。
  • read -r防止带有反斜杠文字的内容被破坏。
  • || [[ $string ]]意味着如果read报告失败,然后我们检查是否填充了字符串,并且如果变量不为空,仍然认为整个命令是成功的。

推荐阅读