2

I have a bash script that is intended to be run from cron. The script counts the words in document, and appends a line with the current time and the word count to a CSV file. In relevant part, the script is:

EPOCH=$(date +"%s")
WCC=$(wc -w ~/path/filename.txt | sed 's/\/Users\/username\/path\/filename.txt//' | sed 's/ //g')
echo $EPOCH,$WCCH4 >> ~/path/wordcount-data.csv

This script is run from cron with the following entry:

0   *   *   *   *   sh /Users/username/path/wordcount.sh

The problem is that wc -w returns a different value when run from cron than when run from the shell or when run from the shell script executed in the terminal. In other words, the value of this script executed from cron is currently 12438, but running wc -w filename.txt in the shell or running sh ./wordcount.sh both return values of 12445. For what it's worth the difference is always 7, and vim's word count matches the word count run from cron.

What accounts for the different values, and how do I fix it?

Lincoln Mullen
  • 6,257
  • 4
  • 27
  • 30
  • Looks like a locale problem. Does your `filename.txt` contain any non-ASCII characters? What `LANG=C wc -w filename.txt` produces? – n. m. could be an AI Mar 26 '12 at 14:00
  • Try running a cron job that simply records the environment that cron sets for you: `/usr/bin/env > /tmp/env.cron`. There will probably be a very minimal set of values set. When the problem is "It works from the command line but not from `cron`", the answer is (99% of the time) [**environment**](http://stackoverflow.com/questions/2229825/where-can-i-set-environment-variables-that-crontab-will-use/). – Jonathan Leffler Mar 26 '12 at 14:04

4 Answers4

2

When you run sh ./wordcount.sh which user is running the script?

I suspect that the user that is executing cron won't be the same, so it's home (~) directory is different.

I'd change any reference to ~ in your script to absolute directory paths.

beny23
  • 34,390
  • 5
  • 82
  • 85
  • A `crontab` file is specific to the user who creates it. The processes run as the user who created it. – Jonathan Leffler Mar 26 '12 at 14:03
  • Thanks for the suggestion. I've changed all the paths to absolute. I've also made the script executable, and now it is called without the `sh` command. As Jonathan Leffler suggests, cron should be running the script as my user. Still, the running the script `./wordcount.sh` and running it from cron return different values for `wc`. Any ideas? – Lincoln Mullen Mar 26 '12 at 15:56
2

Try to add

source ~/.bashrc

after the shebang, and another important thing :

don't call the script with sh if it's bash !

With sh, bash is in POSIX mode. I suspect that's not intended here.

Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
  • I've added `source /Users/lmullen/.bash_profile` to the script. Now the script returns the same value whether called from cron or by `./wordcount.sh`. I suspect that different versions of `wc` have different definitions of what counts as a word, which would also explain the discrepancy between `wc -w` and `vim`'s word count. Thanks. – Lincoln Mullen Mar 26 '12 at 16:03
1

Agreeing with beny23 here, the most common error in cron script sources from the fact, that cron doesn't inherit your PATH. You have to set a cronpath inside the crontab, or use absolute paths.

A second error source might be, that it gets run from a differnt user.

A third one, that you call sh scriptname, not scriptname directly, which means the shebang is ignored. Why do you do so? Isn't the script marked executable?

user unknown
  • 35,537
  • 11
  • 75
  • 121
0

I lost a lot of time with this, and it was just missing at the beginning of the shell script file: #!/bin/bash