Gab*_*enn 15 linux bash gnome-terminal
今天早上我在 bash 终端中有这种奇怪的行为:
user@home:/home/user$ [ -f /etc/openvpn/client.conf ] && echo true
bash: [: missing «]»
user@home:/home/user$ [ -f /etc/openvpn/client.conf ] && echo true
true
Run Code Online (Sandbox Code Playgroud)
经过一番挖掘,我发现删除第 30 个字符(client.conf 和“]”之间的空格)并用空格替换它使命令再次起作用。
我的假设是正确的:命令中出现了一个未知的空白字符,但问题是:
顺便说一句,我运行的是 Ubuntu 18.04 / 法语,我粘贴命令的脚本位于 USB 驱动器中,并且也可能在 Windows 上进行了编辑。
谢谢你的好答案。坏字符是一个c2 a0不间断空格 UTF-8 字符。How to remove special 'M-BM-' character with sed这个问题有关于该角色的有趣事实。
奇怪的是,剧本竟然没有这个角色。所以我不知道它是从哪里来的。
Kiw*_*iwy 18
您可以使用cat以下-A选项:来自手册:
-A, --show-all
equivalent to -vET
-E, --show-ends
display $ at end of each line
-T, --show-tabs
display TAB characters as ^I
-v, --show-nonprinting
use ^ and M- notation, except for LFD and TAB
Run Code Online (Sandbox Code Playgroud)
所以cat -A yourscrip.sh会向你展示隐形和奇怪的字符。
Att*_*tie 11
一种选择是使用十六进制查看器或编辑器查看您尝试使用的字符。hexdump如果您仅限于终端,这是一个不错的选择。
$ hexdump -Cv <<"EOF"
> [ -f /etc/openvpn/client.conf ] && echo true
> EOF
00000000 5b 20 2d 66 20 2f 65 74 63 2f 6f 70 65 6e 76 70 |[ -f /etc/openvp|
00000010 6e 2f 63 6c 69 65 6e 74 2e 63 6f 6e 66 20 5d 20 |n/client.conf ] |
00000020 26 26 20 65 63 68 6f 20 74 72 75 65 0a |&& echo true.|
0000002d
Run Code Online (Sandbox Code Playgroud)
您可以在这里看到space, close-square-brace,space是正确的 - 0x20, 0x5D, 0x20。
这些值是 ASCII 代码,以十六进制显示。范围之外的任何值0x20-0x7E就ASCII 而言,都不是“可打印字符”,并且很可能无法很好地与命令行界面配合使用。
注意:我复制了您的第一个“断”行以用于hexdump上面的示例,因此某些内容已将非 ASCII 空间替换为原始源和呈现的问题之间的 ASCII 空间。
要重复此操作,请执行以下步骤:
hexdump -Cv <<"EOF"并按下EnterEOF一个属于自己的行,然后按Enter终端和命令行界面不能很好地处理特殊字符 - 正如您所发现的。如果您在格式化文档时不是很小心,那么使用“智能引号”、长破折号的Microsoft Word(和其他人)也会遇到问题,列表还在继续……
找出区别:(上边是“智能引号”,下边是“直引号”)

$ hexdump -Cv <<"EOF"
> “quoted string”
> EOF
00000000 e2 80 9c 71 75 6f 74 65 64 20 73 74 72 69 6e 67 |...quoted string|
00000010 e2 80 9d 0a |....|
00000014
Run Code Online (Sandbox Code Playgroud)
在这里,左引号不是简单的 ASCII 引号 ( "),而是一个 Unicode / UTF-8系列 - 0xE2、0x80、0x9C、 或U+201C- 终端不会像您预期的那样处理。
Kiwy 的建议cat -A也可以完成这项工作:
$ cat -A <<"EOF"
> “quoted string”
> EOF
M-bM-^@M-^\quoted stringM-bM-^@M-^]$
Run Code Online (Sandbox Code Playgroud)
注意:使用 时echo "..." | hd,您有可能 bash 会替换您尝试检查的部分字符串。在尝试检查脚本的组件时,这尤其令人担忧。
例如尝试:
$ echo "${USER}"
attie
$ echo "`whoami`"
attie
$ echo "$(whoami)"
attie
$ cat <<EOF
> ${USER}
> EOF
attie
Run Code Online (Sandbox Code Playgroud)
这些方法正在用相关文本替换组件。为避免这种情况,请使用以下方法之一。请注意单引号 ( ') 和“引用的 heredoc ” ( "EOF") 的使用。
$ echo '${USER}'
${USER}
$ echo '`whoami`'
`whoami`
$ echo '$(whoami)'
$(whoami)
$ cat <<"EOF"
> ${USER}
> EOF
${USER}
Run Code Online (Sandbox Code Playgroud)
echo "<your command>" | hd应该管用。查找退格 (0x08) 或代码 >=80 的字符。echo "<your command>" | wc -b并检查计数是否与您看到的相符也是一个好主意。
从名称中带有“Office”的任何文件中复制内容是危险的,因为此类软件通常会随意替换字符:在法语中,注意用“guillemets”替换的双引号,在英语中,将纯引号替换为它们的打开/关闭等价物。我发现的最难的一个是文件名中间的 0 宽度不间断空格(服务器停机 3 天......)。
| 归档时间: |
|
| 查看次数: |
1724 次 |
| 最近记录: |