I am utterly baffled and mystified. I have been happily coding and running Python scripts from the terminal (and also running the Python interpreter). I went to bed a happy user of Python, but suddenly I cannot run any Python script from the shell.
hello.py
contains:
#!/usr/bin/python3
print('Hello world!')
Yet suddenly:
% ./hello.py
./hello.py: 1: #!/usr/bin/python3: not found
./hello.py: 2: Syntax error: word unexpected (expecting ")")
But
% python3 hello.py
Hello world!
% python hello.py
Hello world!
What. The. Zarking. Fardwarks.
ls -la hello.py
shows:
-rwxrwxr-x 1 Lexible Lexible 44 May 25 08:35 hello.py
Per two requests by @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*
shows:
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
For giggles...
% which python
/usr/bin/python
% which python3
/usr/bin/python3
Even...
% 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: I am using Ubuntu 20.04 (Focal Fossa). I have tried rebooting, and sudo apt install -f --reinstall python3 python3.8 python3-minimal python3.8-minimal libpython3.8-minimal
all to no avail.
Since you are able to run the script using
python3 hello.py
, it is evident that the issue isn't with the Python installation or the symlinks. Instead the issue is with the script itself.The shell (here, zsh) didn't really recognize the shebang as such because of some alien characters before
#
. It tried to execute the whole script with the default shell/interpreter, thus producing errors.You can use the
-e
option ofcat
to check the actual contents of the script.-e
is basically the combination ofv
andE
.v
uses^
andM-
notation, andE
displays$
at the end of each line.After observing the output of
cat -e hello.py
, it seems the script contains a byte order mark near its shebang/hashbang which may have been inserted by some Windows software. This prevented the script from actually loading the Python interpreter, so it instead got executed by zsh, thus causing the error.You can remove BOMs and other DOS-specific characters using
dos2unix
.dos2unix
will take care of all Windows/DOS type characters/line endings and convert them to Unix-like ones.Or you can also use
sed
to remove BOMs. Since BOMs were present in UTF-8, their hexadecimal representation isEF BB BF
.With gracious help from @Kulfy the problem seems to be some unrenderable bytes preceding the shebang in my scripts! Specifically, bytes
EF BB BF
preceded the bytes23 21
which should be the start of the script(s).How that byte order mark got there is a mystery, but at least now: