我总是得到
-bash: warning: command substitution: ignored null byte in input
执行以下代码时发出警告:
BW=`bc <<< "$(cat $TMP | grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)')/1024^3"`
如果结果不为零,也会出现该警告。
如何避免这种情况?
当错误真正为0时,如何跳过该错误?
更新,我尝试了以下提供的解决方案:
tr -d '\0'
但是该代码不起作用:
BW=tr -d '\0' < `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
答案 0 :(得分:1)
您会收到警告,因为grep -z
在结果的末尾输出了一个零字节,而Shell无法对此进行处理。最简单的解决方案是删除该选项,或找到一种用Shell实际可以处理的东西替换该选项的方法。实际上,它似乎在这里没有任何用处……但可能会丢失useless cat
并使用现代命令替换语法而不是过时的反引号和fix the quoting.
BW=$(bc <<< "$(grep -Po '(?<="outgoing_traffic": )(.*)(?=,)' <"$TMP")/1024^3")
顺便说一句,tr
命令不起作用的原因之一是您放了反引号。另外,<
之后的符号必须是文件名。正确的语法看起来像
BW=$(bc <<< "$(grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)' <"$TMP" | tr -d '\0')/1024^3")
但是如上所述,如果您不希望零字节,请不要使用-z
选项。
零字节有时有用的原因是,如果要打印文件名,那是文件名中唯一不允许使用的字符,因此在处理文件时用作分隔符是很有用的。 (初学者经常对Unix文件名可以包含引号和换行符感兴趣;但是它们可以。这可能是导致Shell脚本中错误的第一大原因-初学者往往只对琐碎的文件名进行测试,并产生与真实文件名相冲突的代码。 -world文件。)
只需说明一下,零字节不是数字0;它是一个ASCII码为零的字符。 (因此,是ctrl-A之前的字符,它是ASCII代码1,等等。有时您会看到它被称为ctrl- @。)您可以在十六进制转储中看到它,例如:
bash$ echo hello | tr '\n' '\0' | 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家族外壳兼容。如果您需要编写更多的Shell脚本,请阅读有关重定向的介绍。