eluhnabroad
eluhnabroad

Reputation: 443

Another RPi idiot who can't understand cron

Me big dum nooby, no grok cron, pleez you fix brain.

From the pi home directory, I type:

crontab -e

And at the bottom of the file I add a line:

*/5 * * * * date "+(0 6) %H:%M %Z" >> /home/pi/scripts/scripts.log

according to instructions I've read elsewhere while thrashing about on the Web; which I take to mean that every five minutes the system date will be printed to scripts.log. I did add a blank line after this, saved and exited nano, and got the message "crontab: installing new crontab".

I waited, and nothing happened. I went into raspi-config, set the time zone, and rebooted, though that shouldn't matter since it's supposed to run every 5 minutes, not at a specific time. Yes, I created a scripts directory... after the third try... but still nothing. No output at the command line, nothing in the scripts directory, no error messages.

Sorry to rehash what's been covered before, but the threads I've read are all in the context of some specific project, and I don't know enough yet to separate out the info I'm looking for. I just want something, anything, to work using cron, then I'll think about the next thing to screw up.

My abject gratitude and a hollow promise to buy you a beer.

EDIT: Thanks for the referral to another thread, but now I'm confused even more. What script am I supposed to be running? Do commands have to be part of some file, rather than executed directly as if they're typed on the command line? (I hope that makes sense.) Are the lines that start with env >/tmp/test.sh.dummy supposed to be in the script file with the date command, or part of the crontab file?

EDIT 2: OK, so I've RTFM'ed on the Web for several hours, and now I understand that cron only runs scripts. I was laboring under the assumption that it was a sort of "batch file," where commands would be as they would be typed at the command line and executed in the same way.

Let's forget the damn "date" thing, I just want to get this to work at all. I've typed on the command line:

echo "This is a test."

That worked just as I expected. Then I created a shell file, in the scripts directory in the pi directory, called firstscript.sh. It reads as follows:

#!/bin/bash
echo "This is a test."

On the command line, I typed:

sudo chmod +x /home/pi/scripts/firstscript.sh

In the cron table, I've entered the line:

* */2 * * * /home/pi/scripts/firstscript.sh

...With a carriage-return at the end. This is after all the commented lines. There was no #! (hashbang?) at the beginning of the file, so I did not add one. Saved this, got the response crontab: installing new crontab.

If I understand this correctly, it should run every two minutes. Waited 10 minutes. Rebooted, waited another 10. Tried the same, with the command in the crontab line changed to just ./firstscript.sh. Bupkus.

Forgive the long-windedness of this, I just don't know enough about what's going on to know which details are relevant.

Upvotes: 0

Views: 592

Answers (2)

Keith Thompson
Keith Thompson

Reputation: 263497

Me big dum ekspurt, pleez me fix own brain.

I just figured out what the problem is. I've even seen this before, and I really should have recognized this problem when I saw it again.

Quoting the crontab(5) man page:

Percent-signs (%) in the command, unless escaped with backslash (\), will be changed into newline characters, and all data after the first % will be sent to the command as standard input.

The % characters in the arguments to the date command are being intercepted by the cron daemon, and changed into newlines. This is creating an invalid command. You need to change this:

*/5 * * * * date "+(0 6) %H:%M %Z" >> /home/pi/scripts/scripts.log

to this:

*/5 * * * * date "+(0 6) \%H:\%M \%Z" >> /home/pi/scripts/scripts.log

and it should work.

As I mentioned previously in comments, the command in a crontab line does not need to be a shell script. It can be any command that you can execute from a shell prompt, except that it's run in a restricted environment. But in some cases, including this one, you have to be aware that cron will process the command itself before passing it on to /bin/sh to be executed.

Replacing the date command by a shell script that does the same thing would have worked (as long as the script name doesn't include any % characters), but it's not necessary.

Upvotes: 1

S. Adam Nissley
S. Adam Nissley

Reputation: 776

You can Google the following steps:

  1. Create a shell script.
  2. Make sure the script has an appropriate hashbang on the first line.
  3. Mark the script executable.
  4. Try executing it on the command line.
  5. If it works, add it to your crontab.


EDIT:
I have tested and confirmed the OP's findings. I have also tested and confirmed my method shown above.

OP's Method:
Add command to crontab:
OP-1
Produces no results:
OP-2

Method listed above:
1. Create a shell script.
2. Make sure the script has an appropriate hashbang on the first line.
ME-1
3. Mark the script executable.
ME-2
4. Try executing it on the command line. (It worked...)
5. If it works, add it to your crontab.
ME-3
And the results were as expected:
ME-4

Upvotes: 0

Related Questions