Python 3.8 脚本突然无法运行,但直接调用 Python 命令可以正常运行

Python 3.8 脚本突然无法运行,但直接调用 Python 命令可以正常运行

我完全困惑不解。我一直很高兴地从终端编写和运行 Python 脚本(也运行 Python 解释器)。我以 Python 用户的快乐身份上床睡觉,但突然间我无法从 shell 运行任何 Python 脚本。

hello.py包含:

#!/usr/bin/python3
print('Hello world!')

然而突然

% ./hello.py
./hello.py: 1: #!/usr/bin/python3: not found
./hello.py: 2: Syntax error: word unexpected (expecting ")")

% python3 hello.py 
Hello world!
% python hello.py 
Hello world!

什么。Zarking。Fardwarks。


ls -la hello.py显示:

-rwxrwxr-x 1 Lexible Lexible    44 May 25 08:35  hello.py

根据 @Kulfy 的两个请求

% file -k hello.py 
hello.py: Python script text executable\012- a /usr/bin/python3 script, UTF-8 Unicode (with BOM) text executable

% cat -e  hello.py
M-oM-;M-?#!/usr/bin/python3$
print('Hello world!')$

ls -la /usr/bin/python3*显示:

lrwxrwxrwx 1 root root       9 Mar 13 05:20 /usr/bin/python3 -> python3.8
-rwxr-xr-x 1 root root 5457536 Apr 27 08:53 /usr/bin/python3.8
lrwxrwxrwx 1 root root      33 Apr 27 08:53 /usr/bin/python3.8-config -> x86_64-linux-gnu-python3.8-config
lrwxrwxrwx 1 root root      16 Mar 13 05:20 /usr/bin/python3-config -> python3.8-config
-rwxr-xr-x 1 root root     384 Mar 27 19:39 /usr/bin/python3-futurize
-rwxr-xr-x 1 root root     388 Mar 27 19:39 /usr/bin/python3-pasteurize

为了搞笑……

% which python
/usr/bin/python
% which python3
/usr/bin/python3

甚至...

% python3
Python 3.8.2 (default, Apr 27 2020, 15:53:34) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print('Hello world!')
Hello world!
>>>

PS:我正在使用 Ubuntu 20.04(Focal Fossa)。我尝试过重新启动,但sudo apt install -f --reinstall python3 python3.8 python3-minimal python3.8-minimal libpython3.8-minimal都无济于事。

答案1

由于您可以使用 运行该脚本python3 hello.py,因此很明显问题不在于 Python 安装或符号链接。相反,问题在于脚本本身。

由于之前的一些外来字符,shell(此处为 zsh)实际上无法识别 shebang #。它尝试使用默认 shell/解释器执行整个脚本,因此产生错误。

您可以使用以下-e选项cat检查脚本的实际内容。基本上是和-e的组合。使用和符号,并显示在每行末尾。vEv^M-E$

观察输出后cat -e hello.py,似乎脚本包含字节顺序标记在其 shebang/hashbang 附近,可能是由某些 Windows 软件插入的。这导致脚本无法真正加载 Python 解释器,因此它反而由 zsh 执行,从而导致错误。

您可以使用以下方法删除 BOM 和其他 DOS 特定字符dos2unix

dos2unix hello.py  # Install using `sudo apt install dos2unix` (if not already installed)

dos2unix将处理所有 Windows/DOS 类型的字符/行尾并将它们转换为类 Unix 字符/行尾。

或者您也可以使用sed删除 BOM。由于 BOM 存在于 UTF-8 中,因此它们的十六进制表示形式为EF BB BF

sed -i '1s/^\xEF\xBB\xBF//' hello.py

答案2

在 @Kulfy 的慷慨帮助下,问题似乎是我的脚本中 shebang 前面的一些无法渲染的字节!具体来说,这些字节位于脚本开头的EF BB BF字节之前。23 21

字节顺序标记是如何到达那里的仍然是一个谜,但至少现在是:

./hello.py
Hello world!

相关内容