我有这个 Linux shell 命令:
echo $(python3 -c 'print("Test"+"\0"+"M"*18)') | nc -u [IP] [PORT]
我的意图是将print
语句的输出通过管道传递给 netcat 命令。netcat 命令为某些服务创建一个套接字,该套接字实际上返回传入字符串的标准输出。
这里的问题是,当我尝试运行此命令时,我收到以下消息
-bash: warning: command substitution: ignored null byte in input
:我的空字节\0
被忽略了。但我不希望空字节被忽略。
如何告诉系统不要忽略我的空字节并完全按照我指定的方式接收输入。
我已经进行了一些谷歌搜索,但老实说,它们并没有太大帮助。此外,非常感谢任何指向一些精彩文章的链接。
编辑
使用printf
工作。
通常通过python3 -c 'print("Test"+"\0"+"M"*18)'
也有效。重视@cas 解释。我想我可能会坚持,printf
因为它更快(尽管在我的情况下速度并不是特别关心的问题)。
感谢所有做出贡献的人:-)。
bash 中的字符串不能包含 NUL 字节,并且包括命令替换的任何输出。Bash 变量也不能包含 NUL。这不能被忽略或覆盖(尽管它可以在某些命令中解决,例如
printf
,通过\0
用作 NUL\n
的表示,与换行符的表示相同)。您可以将 python 的输出直接通过管道传输到
nc
,而不使用echo
和命令替换(如@CharlieWilson 的回答),但即使这样也没有必要。bash 的printf
内置可以做你想做的事。例如这使用组命令 (
{ list; }
) 首先使用 printf 打印“Test”和 NUL 字节 (\0
),然后再次使用 printf 打印零宽度字符串 (%.0s
) ,然后打印M
18 次。整个 group 命令的输出通过管道传输到nc
.之所以有效,是因为该
printf
格式“根据需要重新使用以使用所有参数”(请参阅help printf
参考资料),并且大括号扩展{1..18}
扩展为从 1 到 18 的整数,为只有一个零的 printf 格式字符串提供十八个参数-width 字符串字段和文字“M”字符。因此,输出了 18 M 个字符。您可以通过将 group 命令通过管道传送到十六进制转储器中来准确地查看输出的内容,例如
xxd
或hd
代替nc
:这样,您可以看到第五个字符是 NUL (
00
)。python 的输出略有不同,因为 python 会
print
自动附加一个换行符 (0a
):如果您发送给它的程序
nc
需要该换行符,您可以使用printf '\n'
. 或与echo
.仅供参考:有关组命令的更多信息,请参阅
man bash
并搜索Compound Commands
:顺便说一句,为此使用 printf 将比使用 python 更快,因为它避免了执行 python 和编译小型 python 脚本的开销......这对于任何类似现代系统的一次性命令都无关紧要,但如果循环运行。例如,在我 10 岁左右的 6 核 AMD Phenom II 1090T 上:
printf 实际上并不需要 0 秒,它需要更多的时间,但是时间太短,无法用我的 $TIMEFORMAT 字符串表示。
Perl 的启动、编译和运行它的小脚本比 python 快一点,但你仍然不想在 shell 循环中重复运行它:
使用 perl 的 printf 甚至更快:
我相信这
echo
是问题所在,而且是不必要的。请考虑这条线。
python3 -c 'print("Test"+"\0"+"M"*18)' | nc -u [IP] [PORT]