【问题标题】:Why are all NUL removed from my script?为什么从我的脚本中删除所有 NUL?
【发布时间】:2012-08-05 00:36:18
【问题描述】:

好像 bash 和 dash 一样,从我的脚本中过滤掉任何 ASCII NUL。

$ printf 'test="\000a" ; echo ${#test}' | sh
1
$ printf 'test="\001a" ; echo ${#test}' | sh
2
$ printf 'ec\000ho test' | sh
test
$ # (Same for bash)

虽然我同意使用 NUL 是一个坏主意(例如,传递给程序的参数适用于以 NUL 结尾的字符串),但我看不出the POSIX standard 认可这种行为的哪些地方。

当这种行为决定文件的语法正确性时,情况会变得更糟。

$ printf 'echo "\\\000"' | sh
sh: Syntax error: Unterminated quoted string
$ printf 'echo "\\\000"' | bash
bash: line 1: unexpected EOF while looking for matching `"'
bash: line 2: syntax error: unexpected end of file
$ printf 'echo "\\\134"' | sh
\

我错过了哪些重要部分,或者 NUL 删除只是关于如何应对未指定行为的决定?

【问题讨论】:

  • 我熟悉的所有 sh 实现都使用 C 字符串,它 - 以 NUL 结尾 - 本质上无法保存 NUL 值。
  • zsh 可以很好地处理所有这些测试用例。
  • 如果@CharlesDuffy 的回答不够,我也会尝试询问 Unix 和 Linux。
  • 我查看了 POSIX 规范,令人惊讶的是,我没有看到任何禁止使用 NUL 的内容。
  • @AlanCurry:先试试printf 'test="\000"; printf "$test" | wc -c' | zsh,然后再试试printf 'test="\000"; /usr/bin/printf "$test" | wc -c' | zsh。不太好:-)

标签: bash sh


【解决方案1】:

sh 标准中的 INPUT FILES 部分指出:

输入文件应为文本文件,但行长不受限制。如果输入文件为空或仅由空行或 cmets 组成,或两者兼有,则 sh 将以零退出状态退出。

术语“文本文件”在第 3.395 节 here 中定义为:

包含组织成零行或多行的字符的文件。这些行不包含 NUL 字符,长度不能超过 {LINE_MAX} 个字节,包括 字符。尽管 POSIX.1-2008 不区分文本文件和二进制文件(参见 ISO C 标准),但许多实用程序仅在对文本文件进行操作时产生可预测或有意义的输出。具有此类限制的标准实用程序总是在其 STDIN 或 INPUT FILES 部分中指定“文本文件”

如果输入不是文本文件(如果它包含零字节则不是),则该行为既无意义也不可预测。

【讨论】:

  • +1 好像是我想要的。这意味着,我认为最好建议在 NUL 上中止实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-21
  • 2020-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-17
  • 2021-04-19
相关资源
最近更新 更多