1

Noob question here. I'm scheduling a cron job for a Python script for every 2 hours, but I want the script to stop running after 48 hours, which is not a feature of cron. To work around this, I'm recording the number of executions at the end of the script in a text file using a tally mark x and opening the text file at the beginning of the script to only run if the count is less than n.

However, my script seems to always run regardless of the conditions. Here's an example of what I've tried:

with open("curl-output.txt", "a+") as myfile:
    data = myfile.read()

    finalrun = "xxxxx"

    if data != finalrun:
        [CURL CODE]

        with open("curl-output.txt", "a") as text_file:
            text_file.write("x")
            text_file.close()

I think I'm missing something simple here. Please advise if there is a better way of achieving this. Thanks in advance.

EricY
  • 376
  • 1
  • 3
  • 19
  • 1
    Why are you using a tally mark? Can't you just use a number? Have you looked at cPickle to easily store data on disk? – Matt Apr 16 '15 at 18:44
  • Can you be a little more clear ? You mention that you append an `x` each time the script is run, so correct me if I am wrong here, but in 48 hours shouldn't the number of `x`'s be 24 ? you are testing the data against 5 `x`'s . – Bhargav Apr 16 '15 at 18:48
  • 1
    Have you looked at `curl-output.txt` to make sure that it looks like what you want? – Micah Smith Apr 16 '15 at 18:49
  • @Bhargav Yes, it should be 24 `x`s. I've used 5 as an example. – EricY Apr 16 '15 at 18:49
  • @Micah Smith Yes, `curl-output.txt` says `xxxxx`, which means the script shouldn't run, but it does. – EricY Apr 16 '15 at 18:50
  • You are using a relative path name which means that the script run in cron will open a different file than the script run on the command line. When you manually check `curl-output.txt` are you looking at the right file? You could change the script to write 'y' and see if it shows up. – tdelaney Apr 16 '15 at 19:14
  • 1
    As an aside, `if len(data) < 24` would be a safer test. – tdelaney Apr 16 '15 at 19:17

5 Answers5

2

The problem with your original code is that you're opening the file in a+ mode, which seems to set the seek position to the end of the file (try print(data) right after you read the file). If you use r instead, it works. (I'm not sure that's how it's supposed to be. This answer states it should write at the end, but read from the beginning. The documentation isn't terribly clear).

Some suggestions: Instead of comparing against the "xxxxx" string, you could just check the length of the data (if len(data) < 5). Or alternatively, as was suggested, use pickle to store a number, which might look like this:

import pickle
try:
    with open("curl-output.txt", "rb") as myfile:
        num = pickle.load(myfile)
except FileNotFoundError:
    num = 0

if num < 5:
    do_curl_stuff()
    num += 1
    with open("curl-output.txt", "wb") as myfile:
        pickle.dump(num, myfile)

Two more things concerning your original code: You're making the first with block bigger than it needs to be. Once you've read the string into data, you don't need the file object anymore, so you can remove one level of indentation from everything except data = myfile.read().

Also, you don't need to close text_file manually. with will do that for you (that's the point).

Community
  • 1
  • 1
dddsnn
  • 2,231
  • 1
  • 12
  • 6
  • I had tried opening the file with `r` and gotten an error, hence the `a+`, but it seems to be working fine now. I removed a level of indentation and the `text_file.close()`. I'm going with `if len(data) < 24:` for now which works smoothly. I will most likely end up using a `+= 1` counter method for more sophistication. I am just trying out different things to learn Python better. Thanks for the suggestions! – EricY Apr 17 '15 at 19:36
1

Well there probably is an end of line jump \n character which makes that your file will contain something like xx\n and not simply xx. Probably this is why your condition does not work :)

EDIT

What happens if through the python command line you type

open('filename.txt', 'r').read() # where filename is the name of your file

you will be able to see whether there is an \n or not

Thomas Gak-Deluen
  • 2,759
  • 2
  • 28
  • 38
  • For the `\n` to be present it has to be added in the script it self right ? – Bhargav Apr 16 '15 at 18:52
  • @tgdn There doesn't seem to be any `\n` when I open the text file. Is it possible that it is still there? – EricY Apr 16 '15 at 18:54
  • You could do `print repr(open('filename.txt', 'r').read())` to see if there are any new lines. But your script doesn't write any and I cant figure out why @tgdn thinks this is the answer. – tdelaney Apr 16 '15 at 19:16
1

Sounds more for a job scheduling with at command?

See http://www.ibm.com/developerworks/library/l-job-scheduling/ for different job scheduling mechanisms.

refnode
  • 11
  • 2
1

The first bug that is immediately obvious to me is that you are appending to the file even if data == finalrun. So when data == finalrun, you don't run curl but you do append another 'x' to the file. On the next run, data will be not equal to finalrun again so it will continue to execute the curl code.

The solution is of course to nest the code that appends to the file under the if statement.

11th Hour Worker
  • 337
  • 3
  • 14
0

Try using this condition along with if clause instead.

if data.count('x')==24

data string may contain extraneous data line new line characters. Check repr(data) to see if it actually a 24 x's.

ByteHamster
  • 4,884
  • 9
  • 38
  • 53
Kalyan
  • 43
  • 6