3

I have a script which I call every 10 minutes with a cronjob:

*/10 * * * * ~/mydirectory/myscript.sh

Now, inside ~/mydirectory there is also another script, let's say myotherscript.sh which I'd like to call from inside myscript.sh. Both scripts have been chmod'ed to be executable and when I execute myscript.sh from the command line inside ~/mydirectory everything works fine. I execute it as follows:

. myscript.sh

But it doesn't look like the cronjob works. When I remove the reference to the second script from inside the primary script, it works though so I suspect there is something wrong with the way I reference the second script. This is what the contents of myscript.sh looks like:

#! /bin/bash
do-something
do-something-else
. myotherscript.sh

Could it be that, when the cronjob runs, the current directory is not ~/mydirectory and so the cronjob can't find the myotherscript.sh file? If so, how to I get it to see the file? I don't want to specify the absolute path inside the primary script as I might want to move it (and myotherscript.sh) to another directory at some point or I might want to rename ~/mydirectory at some point and I don't then want to have to change the contents of myscript.sh to reference the new absolute path.

BONUS QUESTION: Right now, when it's time for the cronjob to execute I basically just hold thumbs and hope for the best but I have no way of seeing whether it was successful and if it failed, why it failed. Any tips on how I can see why the cronjob didn't execute as expected?

5

OK, so glenn jackman's answer works and it also answered my bonus question but I have since figured out another and what I believe to be more elegant way of making sure the cronjob runs in the directory in which the scripts are located.

Simply by replacing

*/10 * * * * ~/mydirectory/myscript.sh

with

*/10 * * * * cd ~/mydirectory && ./myscript.sh

And that solves the problem. Everything works.

2

You are calling the script incorrectly. It should be:

#! /bin/bash
do-something
do-something-else
./myotherscript.sh;
  • Would you mind quickly explaining what the difference between . myotherscript.sh and ./myotherscript.sh is? – Dewald Swanepoel Mar 27 '15 at 20:47
  • 1
    Well im not sure what . myotherscript.sh actually does. I just know through my experience that when I was to call a script within a script I would simply add ./myotherscript.sh;` – ryekayo Mar 27 '15 at 20:48
  • But if i was to guess with glenn's answer, it seems that the . refers to the pwd and then using ./script.sh calls the script... – ryekayo Mar 27 '15 at 20:50
  • 3
    . is the shell's "source" command that reads the script and executes it in the current shell. – glenn jackman Mar 27 '15 at 20:53
  • 1
    That means you're launching the script in a separate process. The difference is important if the other script declares some variables or functions, or changes to another directory, and you rely on those effects in the current shell: . ./other will keep those "side effects" in the current shell; if you use a separate process ./other, then the side effects disappear when the process exits. – glenn jackman Mar 27 '15 at 21:09
2

myscript should have:

cd "$(dirname "$0")"
. ./myotherscript.sh

When cron launches your script, the $PWD might be / so you should go to where your script is located if you want to use relative paths.

You may find it useful to log your script's output:

*/10 * * * * ~/mydirectory/myscript.sh 2>&1 | /usr/bin/ts '[%FT%T]' >> ~/mydirectory/myscript.log

ts adds a timestamp to each line of input. On Fedora and Ubuntu, it's in the moreutils package.

  • I'm not sure I understand the syntax of cd "$(dirname "$0")"? When I add exactly that into me script and try to run it from the command line I get an error "dirname: invalid option -- 'b'" – Dewald Swanepoel Mar 27 '15 at 20:55
  • 1
    @DewaldSwanepoel - read Glenn's answer here. – don_crissti Mar 27 '15 at 21:06
  • @don_crissti, good find. I totally forgot about that. – glenn jackman Mar 27 '15 at 21:12
  • Don't use dirname here - it has the (admittedly extremely unlikely) chance of mangling the directory name which you want to print. cd -- "${0%/*}" will work as well (if either will work at all - if the script being run sets $0 somehow to anything other than a fully qualified path then you're SOL in both cases). – mikeserv Mar 27 '15 at 23:30
0

Defining a PATH and MAILTO within the crontab should help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.