What is the correct way for a bash script to add a job to crontab, such that
- there will be no duplicate jobs
- the crontab file will not be resorted
- (optional) close to being a one-liner
Came across this solution below, but it does not affect the output of running crontab -l
.
grep 'some_user python /mount/share/script.py' /etc/crontab || echo '*/1 * * * * some_user python /mount/share/script.py' >> /etc/crontab
Tried converting it to affect crontab -l
,
(crontab -l | grep '/mount/share/script.py') || { crontab -l; '*/1 * * * * some_user python /mount/share/script.py >> /root/foo/logs/foo.cron.log 2>&1'; } | crontab -
but running this command gives the error:
-bash: */1 * * * * some_user python /mount/share/script.py >> /root/foo/logs/foo.cron.log 2>&1: No such file or directory
CodePudding user response:
but running this command gives the error:
-bash: */1 * * * * some_user python /mount/share/script.py >> /root/foo/logs/foo.cron.log 2>&1: No such file or directory
The code:
(crontab -l | grep '/mount/share/script.py') || { crontab -l; '*/1 * * * * some_user python /mount/share/script.py >> /root/foo/logs/foo.cron.log 2>&1'; } | crontab -
will try to execute/run the:
'*/1 * * * * some_user python /mount/share/script.py >> /root/foo/logs/foo.cron.log 2>&1'
If and when grep
failed.
Add an echo in front of it or printf, since crontab
is expecting input from stdin
, like what you did on your first example/code, something like:
(crontab -l | grep '/mount/share/script.py') || { crontab -l; echo '*/1 * * * * some_user python /mount/share/script.py >> /root/foo/logs/foo.cron.log 2>&1'; } | crontab -
Here is an alternative, which is a full blown script.
#!/usr/bin/env bash
cron_entry=$(crontab -l 2>&1)
is_in_cron='/mount/share/script.py'
new_cron_entry='*/1 * * * * some_user python /mount/share/script.py >> /tmp/foo/logs/foo.cron.log 2>&1'
if [[ $cron_entry != *"$is_in_cron"* ]]; then
printf '%s\n' "$cron_entry" "$new_cron_entry" | crontab -
fi