0

I am trying to get a Python script to run from crontab but it won't.

The script is in /home/osmc/python/test.py

#!/usr/bin/python

# importing modules
import os
import time
import datetime
from datetime import datetime

def f_log(strtext):
# If this method cannot write to the log file, send an email but continue script execution anyway
    logFilePath = '/home/osmc/python/pyscripter_file.txt'
    ts_local = datetime.now()
    ts = ts_local.strftime("%d/%b/%Y %H:%M:%S")

    try:
        # Check if the logfile exists
        if(os.path.isfile(logFilePath)):
            # Append the error message to the log file. 'a+' creates the file if it does not exist.
            with open(logFilePath, 'a+') as f:
                f.write(ts + '\t' + strtext + '\n')
        else:
            print("Log File does not exist - Creating File now")
            with open(logFilePath, 'a+') as f:
                f.write(ts + '\t' + 'Log File does not exist - Creating File now' + '\n')
                f.write(ts + '\t' + strtext + '\n')
    except IOError as e:
        # Handle the exception
        print("you made a booboo")

f_log("Test Script")
print("Hello World")

I made the script executable with ... chmod 744 test.py

ls -l gives this:

-rwxr--r-- 1 root root   937 Oct 11 01:45 test.py

# which python gives /usr/bin/python

This is my crontab which I have under root:

PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/usr/bin/python
01 02 * * * /home/osmc/python/test.py >> out.txt 2>&1

The crontab runs but I get this output in the out.txt file:

/home/osmc/python/test.py: 1: /home/osmc/python/test.py: #!/usr/bin/python: not found
/home/osmc/python/test.py: 4: /home/osmc/python/test.py: import: not found
/home/osmc/python/test.py: 5: /home/osmc/python/test.py: import: not found
/home/osmc/python/test.py: 6: /home/osmc/python/test.py: import: not found
/home/osmc/python/test.py: 7: /home/osmc/python/test.py: from: not found
/home/osmc/python/test.py: 9: /home/osmc/python/test.py: Syntax error: "(" unexpected

This was working for me before and I don't understand why it doesn't anymore??

If I change the crontab to:

PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/usr/bin/python
01 02 * * * /usr/bin/python /home/osmc/python/test.py >> out.txt 2>&1

Now it does work... I see:

"Test Script" in /home/osmc/python/pyscripter_file.txt

And I see: "Hello World" in /root/out.txt

After reading this article.. I thought since I made the python script executable and have the "shebang" line #!/usr/bin/python at the top of the script that I don't need to include /usr/bin/python before /home/osmc/python/test.py in the crontab? I have a python script running like that from crontab on another machine.

Update

I tried getting a hexdump of the python script as suggested by Gordon Davisson enter image description here For some reason additional characters are present before the #!/usr/bin/python on line 1 of the script. This file was created in the PyScripter IDE.

From testing, if I create the file in Notepad++ I don't have this issue. I created test3.py in Notepad++ and the hexdump gives: enter image description here

test3.py will also run from crontab set up like this: enter image description here

I don't need to supply the /usr/bin/python before the full path to the script because I made it executable and have the shebang on the first line. But test.py is also executable and has the shebang on the first line (it is identical to test3.py) however it will not run from crontab.

I created test.py using the file format: UTF-8 and UNIX in PyScripter. It seems that PyScripter is inserting errant characters? They are not visible in the Python IDE so I cannot delete them. How can I stop this?

Flex

FlexMcMurphy
  • 420
  • 5
  • 21
  • 1
    Those errors look a bit like the dash shell is trying to run the script, which suggests the shebang is not being recognized properly. Try doing a hex dump of the script file, and make sure it starts `23 21 2f 75` (that's `#!/u` in hex). If there's anything before that -- a space, a blank line, a unicode byte order mark, whatever -- the shebang will not be recognized. – Gordon Davisson Oct 11 '20 at 02:56
  • Thank you. I think you identified the issue. I updated my question with some more information. I would be very grateful if there is any more help you could give? – FlexMcMurphy Oct 11 '20 at 21:08

3 Answers3

0

Use below first line instead (this is preferred way): #! /usr/bin/env python

see: Python scripts in /usr/bin

Also, you may need to move your executable python to /usr/local/bin/

0

In addition to trying env for the shebang line, you might need to define the python path in your crontab, to support library import. (I have /lib/python but your location to put there might be different.)

PYTHONPATH=$PYTHONPATH:/lib/python
beroe
  • 11,784
  • 5
  • 34
  • 79
0

The problem was happening when I was creating a python script in the PyScripter IDE and choosing the UTF-8 File Format (encoding).

PyScripter IDE includes the Byte Order Mark (BOM) at the start of the encoded script when UTF-8 encoding is selected. This is evidenced by the hex characters: ef bb bf at the start of the string in the hexdump of the script, which was suggested as a debugging measure by Gordon Davisson.

This stops the python script from running in crontab unless the /usr/bin/python is added in before the path to the script. I don't exactly know why that is.

The solution in this case is to choose the UTF-8 (No BOM) as the File Format in PyScripter then the script will run from crontab without having to specify the /usr/bin/python before the path to the script.

FlexMcMurphy
  • 420
  • 5
  • 21