I'm having an issue where when I transfer a Python file to my VPS via FTP and try to run it using ./foo.py I am returned with the error: : No such file or directory.

The error seems to indicate that the file I am trying to execute does not exist. But I can run the program with no problems using python foo.py which leads me to believe that the error actually probably means something else.

At first I thought it could be an issue with the shebang line, so I copied all of the content of the file and pasted it into a new file on the VPS that had not been transferred via FTP. The two files had exactly the same content but when I ran the new file using ./bar.py it ran as expected.

So I've come to the conclusion that this could be an issue with the way that it is transferred. I have switched between ASCII and binary but both of these transfer methods give the same error.

Is it possible to stop this from happening?

  • 2
    On your VPS, does cat -vet ./foo.py | head -1 show any ^M characters? – Mark Plotnick Jun 24 '15 at 20:10
  • Yes: root@vps:/home# cat -vet ./foo.py | head -1 returns #!/usr/bin/env python^M$ – user100599 Jun 24 '15 at 20:20
  • Can you tell us the two OS's you're using, on the originating system and the VPS? – Mark Plotnick Jun 24 '15 at 20:35
  • @MarkPlotnick Both the VPS and my PC are both on Ubuntu. – user100599 Jun 24 '15 at 20:37
  • Did you edit the file at some point on a Windows PC, perchance? – roaima Jun 24 '15 at 20:48

This happens when a file contains \r\n as a line terminator instead of \n, since \r is a C0 control code meaning "go to the beginning of the current line".

To fix, run dos2unix foo.py.

Example session:

ben@joyplim /tmp/cr % echo '#!/usr/bin/env python' > foo.py
ben@joyplim /tmp/cr % chmod +x foo.py 
ben@joyplim /tmp/cr % ./foo.py 
ben@joyplim /tmp/cr % unix2dos foo.py 
unix2dos: converting file foo.py to DOS format ...
ben@joyplim /tmp/cr % ./foo.py       
: No such file or directory
ben@joyplim /tmp/cr % ./foo.py 2>&1 | xxd 
0000000: 2f75 7372 2f62 696e 2f65 6e76 3a20 7079  /usr/bin/env: py
0000010: 7468 6f6e 0d3a 204e 6f20 7375 6368 2066  thon.: No such f
0000020: 696c 6520 6f72 2064 6972 6563 746f 7279  ile or directory
0000030: 0a                                       .

Specifically note the 0d3a in the output.

| improve this answer | |
  • Thanks man! This worked. Really appreciate the help from everyone. – user100599 Jun 24 '15 at 20:47

Could it be a file permission issue?

$ chmod +x foo.py

If you don't specifically indicate you wish to maintain then they are stripped/altered by most ftp clients.

| improve this answer | |
  • I don't think so as the file has been made executable :) – user100599 Jun 24 '15 at 20:25