2

I have a Python Script below that will just run hostname on 4 different hosts and then it will save it to a file. It then will open that file and save these each line or output into a variable which the program will use later. It works fine when I run it manually although everytime I use cronjob I am getting an error.

Note: the whole script is obviously not here if you wondering how I can SSH into these hosts just by the below lines. But the script is failing at the part that I have put below.

Python Script:

#! /usr/bin/python

import os

hostname=['a','b','c','d']

for i in hostname:

    os.system('hostname >> hostlist.txt')

data = open('hostlist.txt')
hosta, hostb, hostc, hostd = data.read().splitlines()

Error:

ValueError: too many values to unpack

Cronjob looks like:

00 14 * * * python /tmp/hostname.py &> /tmp/hostnamerror.log

Update:::

Ok I am pretty sure I know the problem after more troubleshooting. It seems that when I run it with Cronjob that it is not creating the file hostlist.txt, although if I ran it manually then it does create this file. So in the Cronjob it opens hostlist.txt as a new file with no variables hence giving me the error message. Does anyone have any idea why running the Python Script as a Cronjob would cause the redirect in the first os.system command not to create a append and create a file?

aznjonn
  • 113
  • 16
  • In the last line, `data.read().splitlines()` doesn't return 4 values from the file. Python complains because it cannot assign the remaining values to names. If you use `*name` it'll collect the remaining values in a list called `name`. – GIZ Jun 06 '17 at 22:28
  • Well, I am running the command "hostname" and sending it to the file "hostlist" so there should be 4 lines in "hostlist." So shouldnt there be enough values to unpack? – aznjonn Jun 06 '17 at 22:48
  • I dont think anything is wrong with the Python side, since it runs fine alone. Something with running it with a cronjob is making it fail but im not quite sure why – aznjonn Jun 06 '17 at 22:49
  • I don't believe that it's cron either, because it says it has too many values, so it successfully reads a file – Marko Mackic Jun 06 '17 at 23:29
  • @aznjonn add `print(data.read().splitlines())` and prefix the last line with `#` and see what you get in `hostnamerror.log`. – GIZ Jun 07 '17 at 09:10

2 Answers2

0

Interesting and fun.

Have you checked that the file hostlist.txt isn't exceeding 4 values?

The script

I've copied your script and experienced this when running on my host:

user@DESKTOP-RR909JI ~
$ python file.py
Traceback (most recent call last):
  File "file.py", line 12, in <module>
    hosta, hostb, hostc, hostd = data.read().splitlines()
ValueError: too many values to unpack

That happened when the file had more than 4 lines (since you're appending with >> that file will grow all the time) If I had less than 4 values I would receive the error:

ValueError: need more than 3 values to unpack

To avoid that problem I've modified your script by defining a number of hosts, validating that the file isn't empty and finally only reading the amount of lines I need which is the number of hosts I've defined.

#! /usr/bin/python

import os

#---- define the amount of hosts 
hosts = 4

for i in range(0, hosts) :
        os.system('hostname >> hostlist.txt')

#---- check if the file isn't empty
if os.stat("hostlist.txt").st_size == 0 :
    print 'you need values in that file'
else : 
    with open("hostlist.txt") as myfile:
        # only read lines up to the number of hosts
        hosta, hostb, hostc, hostd = [next(myfile) for x in xrange(hosts)]

        print 'this is variable hosta: ' +hosta
        print 'this is variable hostb: ' +hostb
        print 'this is variable hostc: ' +hostc
        print 'this is variable hostd: ' +hostd

I got some inspiration from here, here and here to create the script.

Here's my output:

user@DESKTOP-RR909JI ~
$ python file.py
this is variable hosta: DESKTOP-RR909JI

this is variable hostb: DESKTOP-RR909JI

this is variable hostc: DESKTOP-RR909JI

this is variable hostd: DESKTOP-RR909JI

$ cat hostlist.txt
DESKTOP-RR909JI
DESKTOP-RR909JI
DESKTOP-RR909JI
DESKTOP-RR909JI

The cron job

Are you using root to run that task? Seems like you're adding the job in /etc/crontab* and not using crontab -e because you aren't defining a user.

It could to be related to the user somehow, try to add a different type of crontab job specifying the user like this:

crontab -u -e

This will open the crontab for the specified user (use the account you said to be working when running manually the script).

Be carefull, crontab -e requires explicitly a user to run tasks while /etc/crontab doesn't that's why the amount of columns are different between both options.

Miguel Ortiz
  • 1,412
  • 9
  • 21
  • I am positive that I have 4 values only that append to the file, I have tested this script many times manually. It could be something related to what you are suggesting in the second part with cronjob, as it seems like the cronjob is not creating the file with my >> command which is causing the issue – aznjonn Jun 07 '17 at 14:01
  • I use crontab -e to edit everytime and log in as root user – aznjonn Jun 07 '17 at 14:27
0

Ok I figured it out. For some reason when I run it as a cronjob the double direct was not creating a file so I created the file first then ran the command and it seems to be working now. Thanks everyone for your inputs!!

aznjonn
  • 113
  • 16
  • Cool! I'm glad you were abe to solve it. Then I think os.system('hostname >> hostlist.txt') was not interpreted properly by the shell, hope you've configured your shebang properly. – Miguel Ortiz Jun 07 '17 at 17:50