Crontab - Run in directory
Asked Answered
P

2

250

I would like to set a job to run daily in the root crontab. But I would like it to execute it from a particular directory so it can find all the files it needs, since the application has a bunch of relative paths.

Anyway, can I tell crontab to run from a particular directory?

Phoneme answered 17/1, 2012 at 18:28 Comment(0)
P
473

All jobs are executed by a shell, so start that shell snippet by a command to change the directory.

cd /path/to/directory && ./bin/myapp

Concerning the use of && instead of ;: normally it doesn't make a difference, but if the cd command fails (e.g. because the directory doesn't exist) with && the application isn't executed, whereas with ; it's executed (but not in the intended directory).

Paramedic answered 17/1, 2012 at 18:40 Comment(9)
Rather than add a mostly duplicate answer, let me just add that you can choose which shell (if you need bash rather than sh, for example) by setting SHELL in your crontab.Eft
So this command would be to execute the app (stored in bin) in another directory, wouldn't it? But if you already have the app installed in the right directory, the command I put in my answer would be ok, right? Sorry, I just wan't to understand the question.Internecine
+1. every other related question's solution is to re-write the script with absolute paths. this is exactly what I neededCypher
Out of curiosity, could you use a semi-colon ; instead of the double ampersands && or would that not work? And why?Liddell
@JoshPinter Normally it doesn't make a difference. But if the cd command fails (e.g. because the directory doesn't exist), with &&, the application isn't executed. With ;, it's executed (but not in the intended directory).Masseur
I will do this to all the cron jobs of my apps , you saved me from changing my source files, thank you very muchPhone
I get that this is almost 100X more upvoted than using the man page. But the answer is YES, you CAN tell crontab to run in a certain directory when setting up your cronjob "in the root crontab." Just define its HOME.Wedgwood
@Wedgwood You can't make a cron job to run in a different directory that way. Setting HOME has the incidental effect of starting all jobs in that directory, and is likely to cause the jobs to look for or drop files in unexpected places.Masseur
@Gilles'SO-stopbeingevil' if your limitation is using only one crontab file, you're right. But root level crontab has supported one file per job for decades. "/etc/cron.d (and its siblings cron.daily/weekly/monthly) is preferred for all system crontabs. You shouldn't need to touch /etc/crontab."Wedgwood
W
20

Reading man 5 crontab should tell you that there's a HOME variable set which can be redefined in the file. It becomes your working directory. You can set PATH for the command(s) too. Of course this affects all the cron schedule lines.

E.G.

Several environment variables are set up automatically by the cron(8) daemon. SHELL is set to /bin/sh, and LOGNAME and HOME are set from the /etc/passwd line of the crontab´s owner. HOME and SHELL can be overridden by settings in the crontab; LOGNAME can not.

(Note: the LOGNAME variable is sometimes called USER on BSD systems and is also automatically set).

Depending on your cron of course, but mine also has MAILTO, MAILFROM CONTENT_TYPE, CRON_TZ, RANDOM_DELAY, and MLS_LEVEL.

So for your hypothetical app I'd recommend a file name /etc/cron.d/hypothetical containing:

# Runs hypothetical app @ 00:01Z in its local path for reading its config or something.
SHELL=/bin/sh
HOME=/where/the/app/is
PATH=/where/the/app/is:/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
CRON_TZ=UTC
1 0 * * * theappuser hypothetical --with arguments 

For example with docker-compose relying on the cwd docker-compose.yml:

SHELL=/bin/sh
HOME=/path/to/composed-app
5 5 * * * root docker-compose restart -t 10 service-name
Wedgwood answered 20/10, 2020 at 17:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.