21

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.

  • Note to the folks who edited the title to bring in more information: that was information I gathered after asking the question, based on constructive feedback from the author of the accepted answer. I feel the proposed edit subtracts the intention of my question Why has Python seeming ceased working? which may be useful to others. – Lexible May 27 at 16:11
  • your intention is too vague and broad to be of any use in search results – muru May 27 at 16:12
  • @muru Would be of interest to me, and proposed edit does not speak to my intention as author. – Lexible May 27 at 16:13
47

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 of cat to check the actual contents of the script. -e is basically the combination of v and E. v uses ^ and M- notation, and E 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 hello.py  # Install using `sudo apt install dos2unix` (if not already installed)

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 is EF BB BF.

sed -i '1s/^\xEF\xBB\xBF//' hello.py
| improve this answer | |
  • 3
    Thank you! I removed the mark using hexedit (replacing with spaces, then deleting manually in vi). How the Dickens this byte order mark (TY for the reference! New to me!) got there is a mystery. Not running wine, not running Windows. – Lexible May 25 at 16:55
  • 3
    @Lexible May be an encoding issue on whatever IDE or software you use. I'm not sure about that. You can delete the comments that are outdated to reduce the noise since you've already added outputs to the question :) – Kulfy May 25 at 16:58
  • 2
    My IDE is vim! Perhaps I fat fingered some crazy bit of vim-fu. At any rate, thank you for the gentle tiny education. You are one cool frood. :D – Lexible May 25 at 17:01
  • 2
    @Lexible I had weird invisible characters enter my code when pasting from a website before – xjcl May 26 at 15:09
  • 1
    @xjcl For security reasons, it's highly recommended to avoid copying directly from websites. There are plenty of ways in which a malicious (or incompetent) website operator can obfuscate bad code in their product that may break your machine. – Nzall May 27 at 12:58
8

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 bytes 23 21 which should be the start of the script(s).

How that byte order mark got there is a mystery, but at least now:

./hello.py
Hello world!
| improve this answer | |
  • 1
    One such source is copying code through Skype chat (or similar). For example, the UTF-8 sequence C2 A0 (Unicode non-breaking space, "U+00A0 NO-BREAK SPACE"). The error message would be confusing and not tell anything about what the real problem is - it could be something like "Â : The term 'Â' is not recognized as the name of a cmdlet, function, script file, or operable program." – Peter Mortensen May 26 at 14:07
  • @PeterMortensen Thank you! As it so happens all the scripts I was actually working with were 100% homebrewed. At some point I hope I stumble on how I managed to do this. :) (Also thank you for the edits.) – Lexible May 26 at 16:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.