首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >-bash:警告:命令替换:忽略输入中的空字节

-bash:警告:命令替换:忽略输入中的空字节
EN

Stack Overflow用户
提问于 2020-10-27 08:14:15
回答 1查看 5.2K关注 0票数 1

我总能得到

代码语言:javascript
运行
复制
-bash: warning: command substitution: ignored null byte in input

在执行以下代码时发出警告:

代码语言:javascript
运行
复制
BW=`bc <<< "$(cat $TMP | grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)')/1024^3"`

如果结果不是零,也会出现该警告。

我怎么才能避免呢?

当这个错误真的是0时,我如何跳过它呢?

UPDATE I尝试了下面提供的解决方案:

代码语言:javascript
运行
复制
tr -d '\0' 

但该代码不起作用:

代码语言:javascript
运行
复制
BW=tr -d '\0'  < `bc <<< "$(cat $TMP | grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)')/1024^3"`

输出:

代码语言:javascript
运行
复制
-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

代码语言:javascript
运行
复制
BW=`bc <<< "$(cat $TMP | grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)')/1024^3"`
echo $BW

输出:

代码语言:javascript
运行
复制
-bash: warning: command substitution: ignored null byte in input
4
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-27 09:40:15

您会得到警告,因为grep -z在结果的末尾输出一个零字节,而shell无法处理这个问题。简单的解决方案是放弃该选项,或者找到一种方法将其替换为shell实际上能够处理的东西。实际上,这里似乎没有任何有用的用途.但可能会丢失useless cat,使用现代命令替换语法,而不是过时的回退,以及fix the quoting.

代码语言:javascript
运行
复制
BW=$(bc <<< "$(grep -Po '(?<="outgoing_traffic": )(.*)(?=,)' <"$TMP")/1024^3")

顺便提一下,您的tr命令不能工作的原因之一是您放弃了备份。另外,<后面的符号需要是一个文件名。正确的语法如下所示

代码语言:javascript
运行
复制
BW=$(bc <<< "$(grep -Pzo '(?<="outgoing_traffic": )(.*)(?=,)' <"$TMP" | tr -d '\0')/1024^3")

但是如上所述,如果不想要零字节,就不要放置-z选项。

零字节有时有用的原因是,如果要打印文件名,这是文件名中唯一不允许的字符,因此在处理文件时,它是有用的分隔符。(初学者常常对Unix文件名可以包含引号和换行符等感到好奇,但它们可以。这可能是导致shell脚本中错误的第一原因--初学者倾向于只测试琐碎的文件名,并生成与实际文件相违背的代码。)

为了说明这一点,零字节不是数字0;它是一个ASCII代码为零的字符。(所以它是ctrl-A之前的字符,是ASCII代码1,等等。有时你会看到它被称为ctrl-@。)例如,您可以在十六进制转储中看到它:

代码语言:javascript
运行
复制
bash$ echo hello | tr '\n' '\0' | xxd
00000000: 6865 6c6c 6f00                           hello.

上面的命令将换行符替换为零字节(ASCII代码十六进制00)。您可以省略tr来查看换行符的ASCII代码(十六进制0A,又名ctrl)。

切向,之间的差别

代码语言:javascript
运行
复制
bc <<<"one"

代码语言:javascript
运行
复制
bc <"two"

后者要求从文件two读取输入,而第一个简单地将字符串one作为标准输入传递给bc。还有<<separator,它只在一行中提供文字文本,直到下一次出现separator,作为命令的标准输入(称为“此处文档”)。

所以这就是

代码语言:javascript
运行
复制
echo 2/3 | bc

等于

代码语言:javascript
运行
复制
echo 2/3 > file
bc <file
rm file

代码语言:javascript
运行
复制
cat <<here >file
2/3
here
bc <file
rm file

代码语言:javascript
运行
复制
bc <<<2/3

除了第一个示例或最后一个示例中没有物理文件之外,最后一个示例仅为Bash,而其他示例则与任何Bourne家族shell兼容。如果您需要编写更多的shell脚本,可能会阅读重定向的介绍。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64550414

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档