shebang行无法与cr-lf一起使用


10

为什么以下基本脚本的shebang部分不起作用:

$ cat hello.sh
#! /bin/sh
echo Hello
$ ./hello.sh
bash: ./hello.sh: /bin/sh^M: bad interpreter: No such file or directory

$ cat hello.py
#! /usr/bin/env python3
print("Hello")
$ ./hello.py
: No such file or directory

而手动调用解释器则有效:

$ sh hello.sh
Hello
$ python3 hello.py
Hello

Answers:


11

您的脚本可能具有DOS样式的CR-LF行尾,而不是Unix样式的LF行尾。在第一种情况下,在错误消息中看到的^ M表示0D字符被解释为脚本解释器名称的一部分,而不是行尾的一部分(正如人们可能期望的那样)。由于您的系统上没有包含带有字符0D(^ M)的路径的可执行文件,因此系统无法调用解释器。当您手动调用解释器时,它可以处理脚本中存在的两种行尾。

如果将脚本转换为使用Unix风格的LF行结尾,则应该看到shebang起作用。请继续阅读以获取插图。

在下面的会议中,todos和fromdos是一个实用程序(可在Ubuntu上作为软件包使用tofrodos),用于将行尾约定从CR-LF转换为LF。任何等效的实用程序(请参见此unix.SE问题)都将用于演示。

以下会话记录(使用相同的脚本文件执行)应说明这种情况:

$ fromdos hello.sh
$ ./hello.sh
Hello
$ todos hello.sh
$ ./hello.sh
bash: ./hello.sh: /bin/sh^M: bad interpreter: No such file or directory
$
$ fromdos hello.py
$ ./hello.py
Hello
$ todos hello.py
$ ./hello.py
: No such file or directory
$

似乎这是读取shebang行的内核,显然,Linux内核(至少在我的Kubuntu莽撞的系统上的版本)不能识别CR为结束约定CR-LF线的一部分。

如果脚本的shebang似乎不起作用(即,手动调用脚本上的解释器chmod +x是可行的,但是即使您已经对其进行了操作,也无法使用其文件名执行脚本),那么这可能是原因。

注意:也 感谢其他评论者。如果有更好的答案,我也很高兴听到!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.