-bash:警告:命令替换:忽略输入中的空字节
-bash: warning: command substitution: ignored null byte in input
我总是得到
-bash: warning: command substitution: ignored null byte in input
执行以下代码时出现警告:
BW=`bc <<< "$(cat $TMP | grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)')/1024^3"`
如果结果不为零,也会出现该警告。
我怎样才能避免这种情况?
当它真的是 0 时,如何跳过该错误?
更新 我尝试了下面提供的解决方案:
tr -d '[=13=]'
但是该代码不起作用:
BW=tr -d '[=14=]' < `bc <<< "$(cat $TMP | grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)')/1024^3"`
输出:
-bash: warning: command substitution: ignored null byte in input
-bash: `bc <<< "$(cat $TMP | grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)')/1024^3"`: No such file or directory
有趣的事实,它不是 0
BW=`bc <<< "$(cat $TMP | grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)')/1024^3"`
echo $BW
输出:
-bash: warning: command substitution: ignored null byte in input
4
您收到警告是因为 grep -z
在结果末尾输出零字节,而 shell 无法处理。简单的解决方案是删除该选项,或找到一种方法将其替换为 shell 实际上可以处理的内容。实际上,它在这里似乎没有任何用处...但可能会丢失 useless cat
and use modern command substitution syntax instead of the obsolescent backticks, and fix the quoting.
BW=$(bc <<< "$(grep -Po '(?<="outgoing_traffic": )(.*)(?=,)' <"$TMP")/1024^3")
顺便说一句,您的 tr
命令不起作用的一个原因是您去掉了反引号。此外,<
之后的符号需要是文件名。正确的语法看起来像
BW=$(bc <<< "$(grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)' <"$TMP" | tr -d '[=11=]')/1024^3")
但如上所述,如果您不想要零字节,请不要放置 -z
选项。
零字节有时有用的原因是,如果您正在打印文件名,这是唯一不允许出现在文件名中的字符,因此在处理文件时它可用作分隔符。 (初学者经常对 Unix 文件名可以包含引号和换行符等感到好奇;但他们可以。这可能是 shell 脚本中错误的第一大原因 - 初学者往往只测试琐碎的文件名,并生成代码与 real-world 个文件一起中断。)
为了说明这一点,零字节 不是数字 0;它是一个 ASCII 码为零的字符。 (所以它是 ctrl-A 之前的字符,它是 ASCII 码 1,等等。有时你会看到它被称为 ctrl-@。)你可以在十六进制转储中看到它,例如:
bash$ echo hello | tr '\n' '[=12=]' | xxd
00000000: 6865 6c6c 6f00 hello.
以上命令用零字节(ASCII 码十六进制 00)替换换行符。您可以省略 tr
以查看换行符的 ASCII 代码(十六进制 0A,又名 ctrl-J)。
相切,两者的区别
bc <<<"one"
和
bc <"two"
是后者说要从文件 two
中读取输入,而第一个只是将字符串 one
作为标准输入传递给 bc
。还有 <<separator
提供直到下一次出现 separator
的文字文本作为命令的标准输入(称为“此处文档”)。
所以这个
echo 2/3 | bc
等同于
echo 2/3 > file
bc <file
rm file
或
cat <<here >file
2/3
here
bc <file
rm file
或
bc <<<2/3
除了第一个例子和最后一个例子没有物理文件,最后一个例子只有Bash,其他的都兼容Bourne-family shell。如果您需要编写更多 shell 脚本,请阅读重定向简介。
我总是得到
-bash: warning: command substitution: ignored null byte in input
执行以下代码时出现警告:
BW=`bc <<< "$(cat $TMP | grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)')/1024^3"`
如果结果不为零,也会出现该警告。
我怎样才能避免这种情况?
当它真的是 0 时,如何跳过该错误?
更新 我尝试了下面提供的解决方案:
tr -d '[=13=]'
但是该代码不起作用:
BW=tr -d '[=14=]' < `bc <<< "$(cat $TMP | grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)')/1024^3"`
输出:
-bash: warning: command substitution: ignored null byte in input
-bash: `bc <<< "$(cat $TMP | grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)')/1024^3"`: No such file or directory
有趣的事实,它不是 0
BW=`bc <<< "$(cat $TMP | grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)')/1024^3"`
echo $BW
输出:
-bash: warning: command substitution: ignored null byte in input
4
您收到警告是因为 grep -z
在结果末尾输出零字节,而 shell 无法处理。简单的解决方案是删除该选项,或找到一种方法将其替换为 shell 实际上可以处理的内容。实际上,它在这里似乎没有任何用处...但可能会丢失 useless cat
and use modern command substitution syntax instead of the obsolescent backticks, and fix the quoting.
BW=$(bc <<< "$(grep -Po '(?<="outgoing_traffic": )(.*)(?=,)' <"$TMP")/1024^3")
顺便说一句,您的 tr
命令不起作用的一个原因是您去掉了反引号。此外,<
之后的符号需要是文件名。正确的语法看起来像
BW=$(bc <<< "$(grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)' <"$TMP" | tr -d '[=11=]')/1024^3")
但如上所述,如果您不想要零字节,请不要放置 -z
选项。
零字节有时有用的原因是,如果您正在打印文件名,这是唯一不允许出现在文件名中的字符,因此在处理文件时它可用作分隔符。 (初学者经常对 Unix 文件名可以包含引号和换行符等感到好奇;但他们可以。这可能是 shell 脚本中错误的第一大原因 - 初学者往往只测试琐碎的文件名,并生成代码与 real-world 个文件一起中断。)
为了说明这一点,零字节 不是数字 0;它是一个 ASCII 码为零的字符。 (所以它是 ctrl-A 之前的字符,它是 ASCII 码 1,等等。有时你会看到它被称为 ctrl-@。)你可以在十六进制转储中看到它,例如:
bash$ echo hello | tr '\n' '[=12=]' | xxd
00000000: 6865 6c6c 6f00 hello.
以上命令用零字节(ASCII 码十六进制 00)替换换行符。您可以省略 tr
以查看换行符的 ASCII 代码(十六进制 0A,又名 ctrl-J)。
相切,两者的区别
bc <<<"one"
和
bc <"two"
是后者说要从文件 two
中读取输入,而第一个只是将字符串 one
作为标准输入传递给 bc
。还有 <<separator
提供直到下一次出现 separator
的文字文本作为命令的标准输入(称为“此处文档”)。
所以这个
echo 2/3 | bc
等同于
echo 2/3 > file
bc <file
rm file
或
cat <<here >file
2/3
here
bc <file
rm file
或
bc <<<2/3
除了第一个例子和最后一个例子没有物理文件,最后一个例子只有Bash,其他的都兼容Bourne-family shell。如果您需要编写更多 shell 脚本,请阅读重定向简介。