Linux 带有特殊字符的 cat 内联文件

Linux cat inline file with special characters

我有以下脚本:

#!/bin/bash
cat << EOF
A^@B^AC^B
EOF

其中:

因此,文件如下所示:

xxd main.sh
00000000: 2321 2f62 696e 2f62 6173 680a 0a63 6174  #!/bin/bash..cat
00000010: 203c 3c20 454f 460a 4100 4201 4302 0a45   << EOF.A.B.C..E
00000020: 4f46 0a                                  OF.

当我 运行 脚本时,十进制值 0 和 1 似乎消失了:

./main.sh | xxd
00000000: 4142 4302 0a                             ABC..

我的问题是为什么?我期待有这样的输出:

字符'A',后面跟着十进制值0,后面跟着'B',后面跟着十进制值1,后面跟着'C',后面跟着十进制值2。

原因似乎有两个。

首先,请注意您必须 here-document 中引用单词 /定界符 以避免扩展 :

If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion, the character sequence \newline is ignored, and ‘\’ must be used to quote the characters ‘\’, ‘$’, and ‘`’.

所以,如果你这样写:

#!/bin/bash
cat <<"EOF"
A^@B^AC^B
EOF

您将保留除 NULL ([=11=]) 之外的所有字符。

但是您不能在任一变量或命令行的参数中使用 NULL 字符(参见this answer)。

不过,您 可以在 pipes/files 中使用 NULL,因此您可能希望对此处文档的内容进行编码并即时解码(例如使用 xxd).

在进一步思考这个问题后,我意识到引用 word/delimiter(如其他答案所建议的)不应该影响脚本的输出(参数扩展、命令替换和算术扩展不影响正在我的脚本中执行)。

因此,[=10=]0 确实消失了,因为您不能在变量或命令行参数中使用 NULL 字符。

但是,[=11=]1 由于 bash 错误而消失了。 bash 在内部使用该值作为转义字符。该错误出现在函数 expand_word_internal 中,它没有正确处理该转义字符(请参阅错误报告 here)。

该错误已在 bash 开发分支中修复。