尝试了以下shebang行:
$ head -n2 .bashrc | od -c
0000000 357 273 277 # ! / b i n / b a s h \n
$ bash
bash: #!/bin/bash: No such file or directory
.bashrc 以空行开头据称(前三个字符不可见):
$ head -n2 .bashrc | od -c
0000000 357 273 277 \n # ! / b i n / b a s h \n
$ bash:
: command not found
在该行之后,bashrc 行将正常执行,因此功能不受影响。但是我发现这个错误非常烦人。
我希望这篇文章能对某些人有所帮助。
答案1
您的文件不是以 开头的#!/bin/bash
,而是以三字节序列 357 273 277 开头(其中每个字节都以八进制输入;即更常见的十六进制中的 ef bb bf)是 Unicode 字符 U+FEFF ZERO WIDTH NO-BREAK SPACE 的 UTF-8 编码。请注意角色结尾(字符或字符序列与字节序列之间的对应关系,例如 UTF-8)和字符集(字符和其表示之间的对应关系,例如 Unicode),因为它在这里很重要。
字符 U+FEFF 也称为字节顺序标记 (BOM). 此字符用于编码为UTF-16UTF-16 采用以两个字节为单位的表示方式,每个单元内的字节可以按任意顺序排列:大端或小端(它只需在一个文本文件内保持一致即可)。BOM 字符用于指示以 UTF-16 编码的文件的字节序(对称字符 U+FFFE 故意未分配,因此前两个字节只能在两种可能的字节序之一中有效)。
U+FEFF 的 BOM 解释仅在具有字节顺序的编码(例如 UTF-16)中才有意义。UTF-8 编码没有字节顺序的概念,因为字符是以具有明确定义的顺序的(可变大小)字节序列进行编码的。因此,在 UTF-8 中,字节序列 ef bb bf 只是字符 U+FEFF,它只是另一个非 ASCII Unicode 字符。
与许多其他程序一样,Bash 将所有非ASCII字符是可以出现在字符串中的普通字符。对于 bash,字符串包括裸词。这样做的好处是,只要该编码是 ASCII 的超集,bash 就可以处理任何编码的输入,即 ASCII 集中的字符用它们的 ASCII 编码值编码为一个字节。UTF-8 就是这样一种编码。U+FEFF 是零宽度空格,因此对人类是不可见的,但对程序是可见的。以 Unicode 解释其输入的程序可能会将其视为空格字符,但将其输入解释为 ASCII 加上无意义的非 ASCII 字符的程序则不会这样做。
在您的文件中,bash 看到一个初始的 14 个字节序列,它将其解析为普通字符:ef bb bf 23 21 2f 62 69 6e 2f 62 61 73 68。前三个字符在 UTF-8 编码中编码为 U+FEFF;bash 的解析器不关心编码,并将它们视为三个普通字符。第四个字符#
不是注释起始字符,因为它不在单词的开头。生成的 14 个字符的单词被解释为命令名称,并且没有该名称的命令。
与大多数其他程序文本一样,Shell 脚本必须使用与 ASCII 兼容的编码编写。请确保您的编辑器不会在换行符前添加虚假字符,例如回车符(Windows 的行尾编码,但 Unix 程序将回车符视为普通字符)或在开头添加 U+FEFF。无论如何,U+FEFF 只是在以 UTF-16 编码的文件开头的字节顺序标记;当它用在以 UTF-8 编码的文件开头时,它只是一个无用的开头空格。如果编辑器在 UTF-8 文件的开头添加 U+FEFF,那就是一个错误。
除此之外,在 的顶部使用 shebang 行是没有用的.bashrc
。虽然它不会造成任何伤害(这里的伤害是因为您实际上没有有效的 shebang 行),但它是虚假的并且可能会造成混淆。该文件永远不会作为独立脚本执行。
答案2
解决了通过备份 .bashrc 来解决问题:
mv .bashrc ..bashrc
# recreating .bashrc:
touch .bashrc
$ bash # returns no errors !!!
使用vim编辑.bashrc文件后,其内容如下:
head -n2 .bashrc | od -c
0000000 # ! / b i n / e c h o " T e s
0000020 t " \n
罪魁祸首似乎是这三个无形的我的 .bashrc 开头的字符:“357 273 277”。起初我以为这些字符属于我的 .bashrc 文件,所以我把它们留在那里。要花一段时间才能找到我的哪个编辑器以这种方式破坏了文件。
我希望这篇文章能对某些人有所帮助。