0

I am trying to execute a python script (with chmod +x) which accepts several options via cronjob. One option is a password which I don't want to store in the crontab file, so I saved it with chmod 600 in my user's home directory (OS: raspbian). My crobtab line is:

* * * * 5 [ $(date +\%d) -le 07 ] && /opt/scripts/myscript.py -p '$(< /home/pi/mypasswordfile)'  >> /tmp/backup.log 2>&1

The line

/opt/scripts/myscript.py -p '$(< /home/pi/mypasswordfile)'  >> /tmp/backup.log 2>&1

is executed correctly with bash, but not from the crontab. This is correct as crontab does not execute a bash - but how to do it correctly?

Thanks in advance!

drohhyn
  • 5
  • 2

4 Answers4

3

I generally recommend against putting any complex syntax directly into crontab files. Put it into a script, and run the script from crontab. So create a script like runmyscript.sh that contains:

#!/bin/bash
if [ $(date +%d) -le 7 ] 
then
    /opt/scripts/myscript.py -p "$(< /home/pi/mypasswordfile)"
fi

and change the crontab to:

* * * * 5 /opt/scripts/runmyscript.sh >> /tmp/backup.log 2>&1
Barmar
  • 741,623
  • 53
  • 500
  • 612
1

Simply add

SHELL=/bin/bash

to your crontab file, to use bash instead of /bin/sh to execute the commands.

chepner
  • 497,756
  • 71
  • 530
  • 681
1

You could just capture your password and pass it as an argument using cat & backticks:

/opt/scripts/myscript.py -p `cat /home/pi/mypasswordfile` >> /tmp/backup.log

Disclosure: backticks have been deprecated in favor of $() but sometimes just doesn't fit the scenario.

Rafael Aguilar
  • 3,084
  • 1
  • 25
  • 31
0

I would try:

bash -c '/opt/scripts/myscript.py -p $(< /home/pi/mypasswordfile)'

Also, sometimes you might need to pass environmental variables, specially DISPLAY for some programs to run correctly, for example:

* * * * 5 env DISPLAY=:0 [ $(date +\%d) -le 07 ] && bash -c '/opt/scripts/myscript.py -p $(< /home/pi/mypasswordfile)'  >> /tmp/backup.log 2>&1
Jamil Said
  • 2,033
  • 3
  • 15
  • 18
  • You need to put the whole argument inside single quotes. – Barmar Jan 06 '17 at 20:25
  • Not sure I follow you. I removed his single quotes, was that it? Can you please enlighten me? – Jamil Said Jan 06 '17 at 20:31
  • Change your double quotes to single quotes. Otherwise, `$(...)` is seen by `/bin/sh`, and it doesn't like it. – Barmar Jan 06 '17 at 20:33
  • http://stackoverflow.com/questions/6697753/difference-between-single-and-double-quotes-in-bash – Barmar Jan 06 '17 at 20:33
  • @Barmar thank you for your comments, feedback is always appreciated. I know the difference between single and double quotes, but I fail to see why the usage above would be problematic. In my view, either single or double quotes on `bash -c "/opt/scripts/myscript.py -p $(< /home/pi/mypasswordfile)"` would work fine, would it not? – Jamil Said Jan 06 '17 at 20:43
  • No, because when you put it in double quotes, the `$` is processed by the original shell, not the shell run by `bash -c`. – Barmar Jan 06 '17 at 20:43
  • But in single quotes the `$(...)` will not expand, right? I just tried `var=hi; bash -c 'echo $var'` and the `var` did not expand. – Jamil Said Jan 06 '17 at 20:52
  • Try: `bash -c 'var=foo; echo $var'`. – Barmar Jan 06 '17 at 20:54
  • Or `export var=hi; bash -c 'echo $var'`. – Barmar Jan 06 '17 at 20:54
  • You didn't export the variable, so it doesn't exist in the new shell. – Barmar Jan 06 '17 at 20:55
  • Correct. Thank you for all the explanations, I changed my answer. The point using double quotes in this case would expand the `$` on the original shell rather than on the targeted `bash -c` shell is an insight I missed. Many thanks for pointing it out. – Jamil Said Jan 06 '17 at 21:01
  • No problem. Quoting can get very complicated when you have nested shell invocations like this. That's why I try to avoid it, see my answer. – Barmar Jan 06 '17 at 21:02
  • Yes, I follow the same approach as your answer (and thus I upvoted it), but I tried to answer here in the same style as the OP crafted it (maybe I shouldn't, that's why I made this oversight). Just one more question if you can indulge me: in this context, would `bash -c '/opt/scripts/myscript.py -p "$(< /home/pi/mypasswordfile)"'` be ok or would the `$(...)` part be picked up by the original shell? – Jamil Said Jan 06 '17 at 21:08