1

I'm trying to add a piece of code to my script that will update its own entry in crontab. So far, I've been working with with the following:

crontab -u root -l | grep -w "$VAR" | crontab -u root - && { crontab -l -u root 2>/dev/null; echo "0 */2 * * * /root/$VAR/script > /dev/null 2>&1"; } | crontab -u root -

The objective is to have this run on several scripts and all of them will find and update its own line, based on $VAR.

For example:

script1

#!/bin/bash
VAR="home1"

crontab -u root -l | grep -w "$VAR" | crontab -u root - && { crontab -l -u root 2>/dev/null; echo "0 */2 * * * /root/$VAR/script > /dev/null 2>&1"; } | crontab -u root -

echo "Hi"

exit 0

script2

#!/bin/bash
VAR="home2"

crontab -u root -l | grep -w "$VAR" | crontab -u root - && { crontab -l -u root 2>/dev/null; echo "0 */2 * * * /root/$VAR/script > /dev/null 2>&1"; } | crontab -u root -

echo "Hi"

exit 0

What I'm trying to add is have these scripts create the following crontab:

0 */2 * * * /root/home1/script > /dev/null 2>&1

0 */2 * * * /root/home2/script > /dev/null 2>&1

For some reason the last running overwrites all entries.

Any tips? Thank you!

1

Using a file or standard input to configure crontab newly creates (overwrites) the contents rather than appends to whatever might already exist.

One easy solution would be to write each of your entries to a single file:

crontab -u root -l | grep -w "$VAR" | crontab -u root - && \
    { crontab -l -u root 2>/dev/null; echo "0 */2 * * * /root/$VAR/script > /dev/null 2>&1"; } \
    >> cron-entry-file

Then after you've collected all the entries do this just once:

crontab -u root cron-entry-file

If you are generating your entries in different scripts and/or at different times then each time you would need to do: crontab -l > cron-entry-file to preserve current settings, then follow the steps above. (Hopefully someone comes along with a more graceful solution but this brute-force approach should work.)


Edit

Since your scenario is not quite as straightforward as I thought when originally writing the above consider manipulating the crontab file directly. It's just a regular file (under /var/cron/tabs/{username} for example). Might want to read this first: https://serverfault.com/questions/347318/is-it-bad-to-edit-cron-file-manually

  • Would that scale to several scripts? My objective is to have each script updating its own line in crontab. Let's say that each script would create its own cron-entry-file, when I add it with 'crontab -u root cron-entry-file' only the most recent one would apply, no? – t988GF Jun 17 '17 at 13:35
  • You're right. If you have no way for your scripts to append to a single file (e.g. if you run scripts at different times) then you'd need to preserve the existing crontab value in a file and append to that. I added details to my answer describing this scenario. – B Layer Jun 17 '17 at 13:51
  • Couldn't I just create a cron file for each script, each script would update its own file, and cron would run off of that? Since the scripts will be running at the same time, this way each script would have its own file to work on, and not have to rely on crontab. – t988GF Jun 17 '17 at 14:21
  • I'm trying a different approach, where each script will create its own file, named after $VAR, in /etc/cron.d/ – t988GF Jun 17 '17 at 14:30
  • Or you could bypass the crontab command altogether...see latest edit to my answer. – B Layer Jun 17 '17 at 14:48
0

I found that the best way to have a script update cron entries is to direct them to a separate file and have cron feed off of that. With the example I provided in the question, I ended up doing the following:

echo "0 */2 * * * root /root/$VAR/script > /dev/null 2>&1" > /etc/cron.d/$VAR

This will create the file named after the variable on /etc/cron.d/ and will follow the schedule defines in the file itself. Cleaner than managing crontab, as recommended in this thread.

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.