-1

Possible Duplicate:
executing a sh script from the cron

I'm having issues with a script that I created and am trying to run via cron. The script works perfectly fine when manually executed, but when i put it into /etc/cron.hourly, some parts don't work. I've seen similar questions ask this and the answer generally refers to cron's limited environment and something about using full paths. Here's a similar question: executing a sh script from the cron

Here is a stripped down version of the script I'm trying to run.

#!/bin/sh
#Run download script to download product data
cd /home/dir/Scripts/Linux
sh script1.sh

#Run import script to import product data to MySQL
cd /home/dir/Mysql
sh script2.sh

#Download inventory stats spreadsheet and rename it
cd /home/dir
wget http://www.url.com/file1.txt
mv file1.txt sheet1.csv

#Remove existing export spreadsheet
rm /tmp/sheet2.csv

#Run MySQL queries in "here document" format
mysql database_name << EOF

--Drop old inventory stats table
truncate table table_name1;

--Load new inventory stats into table
Load data local infile '/home/dir/sheet1.csv' into table table_name1 fields terminated by ',' optionally enclosed by '"' lines terminated by '\r\n';

--MySQL queries to combine product data and inventory stats here

--Export combined data in spreadsheet format
group by p.value into outfile '/tmp/sheet2.csv' fields terminated by ',' optionally enclosed by '"' lines terminated by '\r\n';
EOF

I know that part of it is working because /tmp/sheet2.csv is being deleted as per the 16th line. However, no new /tmp/sheet2.csv is being exported, as it should be at the end of the script.

Any ideas on how to fix this? I'm not too advanced, so I'm not clear on how to resolve the issue of cron's limited environment.

Nick
  • 315
  • 2
  • 7
  • 15

2 Answers2

2

You already wrote it. Use full or relative paths for all of your commands.

If you want to execute other scripts do use /bin/sh ./another.sh

In your interactive shell - does PATHcontain the current directory (.)? This is basically a security risk and cron does not add it to its PATH-setting.

Nils
  • 7,695
  • 3
  • 34
  • 73
  • Will I have to use full paths for `wget` and `mysql`? Also, I don't understand what you are talking about in your last question. Sorry, newb here. – Nick Aug 02 '11 at 20:29
  • Yes - it is better to use a full path for all commands. In your shell do a `echo $PATH` and post the result. – Nils Aug 02 '11 at 20:35
  • `/usr/local/jdk/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/lib/courier-imap/sbin:/usr/lib/courier-imap/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/X11R6/bin:/root/bin` – Nick Aug 02 '11 at 20:41
  • When you say all commands, does this mean `cd`, `mv`, `rm`? Also, where can I find a list of the absolute paths for these commands? – Nick Aug 02 '11 at 20:44
  • @Nick: No, `cd`, is a shell builtin, there is no executable for it. For all else, you get a full path with `which mv` etc. – Sven Aug 02 '11 at 20:50
  • But you don't need this for these basic commandos. To see your `PATH` variable from inside the cron enviroment, add the command `echo $PATH > /tmp/cronpath` to your script. After it executed, you can display this file to see the path. – Sven Aug 02 '11 at 20:53
  • @SvenW Thanks. `which` worked for `wget`, `mysql`, and `sh`. However, when I ran it for `mv` and `rm`, there was no response/output. – Nick Aug 02 '11 at 20:55
  • @Nick: This means that it's a shell builtin with your current shell as well. – Sven Aug 02 '11 at 20:57
2

One thing: The path is more restricted in the cron environment, so it's a good idea to use absolute paths for the commands you use, especially for the mysql command.

Also, it's likely that mysql can't connect to your database without any username/password. Again, it's not running in your normal environment, where you might have enviroment variables or configuration files present to allow you to use mysql without options.

To help you debugging a cron script, you can try redirecting command outputs into a temporary file.

Sven
  • 98,649
  • 14
  • 180
  • 226
  • I read somewhere that it's recommended to connect to the database with username/pass within the mysql block as opposed to in the same line as the mysql command because it's more secure. In my case it would be something like `mysql << EOF`, next line: `-u username -ppass`. This is obviously the wrong syntax, but do you know what the right syntax would be? Sorry if that's unclear. – Nick Aug 02 '11 at 21:08
  • On a multiuser system, it's indeed a bad idea to put the password onto the command line, as it will show up with `ps` etc. If you don't expect to have any other users on this system, it's not so big an issue as anyone who might see this is an intruder who already gained control of your machine. – Sven Aug 02 '11 at 21:18
  • Anyway, I don't know if you can put your credentials into a heredoc with `mysql`, but you put them into an config file, either into `~/.my.cnf` or in another file you specify with the option `--defaults-extra-file=filename`. It must include at least two lines: `user=username` and `password=yourpassword`. Beware that this config files must not be world-writable. – Sven Aug 02 '11 at 21:23