How do I add/remove cron jobs by script?
up vote
4
down vote
favorite
I'm going to make a bash script that is executed at boot and runs periodically.
I want it user-configurable, so that a user can add a cron job 0 * * * * my_script
by running my_script add 0 * * * *
, list jobs by my_script list
, and remove by my_script remove job_number
where the job number is listed in the output of my_script list
command.
If I could manage crontab files separately, this would be easily achieved.
However, It seems crontab is only one file per a user (If not, please let me know). Directly dealing with that crontab file is a bad solution, of course.
So what is the proper way to handle the cron jobs? Or, is there a better way to handle periodically running scripts?
Conditions:
- Any user should be able to run it, whether privileged or not.
- No dependencies.
Additional question:
Since I couldn't find any proper way to manage periodically running scripts, I thought what I might be doing wrong. In the sense of software design, is it not practical to implement the interface to manage the software's scheduled tasks? Should I leave all schedule managements to users?
shell-script cron
add a comment |
up vote
4
down vote
favorite
I'm going to make a bash script that is executed at boot and runs periodically.
I want it user-configurable, so that a user can add a cron job 0 * * * * my_script
by running my_script add 0 * * * *
, list jobs by my_script list
, and remove by my_script remove job_number
where the job number is listed in the output of my_script list
command.
If I could manage crontab files separately, this would be easily achieved.
However, It seems crontab is only one file per a user (If not, please let me know). Directly dealing with that crontab file is a bad solution, of course.
So what is the proper way to handle the cron jobs? Or, is there a better way to handle periodically running scripts?
Conditions:
- Any user should be able to run it, whether privileged or not.
- No dependencies.
Additional question:
Since I couldn't find any proper way to manage periodically running scripts, I thought what I might be doing wrong. In the sense of software design, is it not practical to implement the interface to manage the software's scheduled tasks? Should I leave all schedule managements to users?
shell-script cron
add a comment |
up vote
4
down vote
favorite
up vote
4
down vote
favorite
I'm going to make a bash script that is executed at boot and runs periodically.
I want it user-configurable, so that a user can add a cron job 0 * * * * my_script
by running my_script add 0 * * * *
, list jobs by my_script list
, and remove by my_script remove job_number
where the job number is listed in the output of my_script list
command.
If I could manage crontab files separately, this would be easily achieved.
However, It seems crontab is only one file per a user (If not, please let me know). Directly dealing with that crontab file is a bad solution, of course.
So what is the proper way to handle the cron jobs? Or, is there a better way to handle periodically running scripts?
Conditions:
- Any user should be able to run it, whether privileged or not.
- No dependencies.
Additional question:
Since I couldn't find any proper way to manage periodically running scripts, I thought what I might be doing wrong. In the sense of software design, is it not practical to implement the interface to manage the software's scheduled tasks? Should I leave all schedule managements to users?
shell-script cron
I'm going to make a bash script that is executed at boot and runs periodically.
I want it user-configurable, so that a user can add a cron job 0 * * * * my_script
by running my_script add 0 * * * *
, list jobs by my_script list
, and remove by my_script remove job_number
where the job number is listed in the output of my_script list
command.
If I could manage crontab files separately, this would be easily achieved.
However, It seems crontab is only one file per a user (If not, please let me know). Directly dealing with that crontab file is a bad solution, of course.
So what is the proper way to handle the cron jobs? Or, is there a better way to handle periodically running scripts?
Conditions:
- Any user should be able to run it, whether privileged or not.
- No dependencies.
Additional question:
Since I couldn't find any proper way to manage periodically running scripts, I thought what I might be doing wrong. In the sense of software design, is it not practical to implement the interface to manage the software's scheduled tasks? Should I leave all schedule managements to users?
shell-script cron
shell-script cron
edited May 6 '17 at 14:01
Jeff Schaller
37.9k1053123
37.9k1053123
asked May 6 '17 at 13:06
queued
2313
2313
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
up vote
6
down vote
accepted
Using cron is the correct way to schedule periodic running of tasks on most Unix systems. Using a personal crontab is the most convenient way for a user to schedule their own tasks. System tasks may be scheduled by root (not using the script below!) in the system crontab, which usually has an ever so slightly different format (an extra user field).
Here's a simple script for you. Any user may use this to manage their own personal crontab.
It doesn't do any type of validation of its input except that it will complain if you give it too few arguments. It is therefore completely possible to add improperly formatted crontab entries.
The
remove
sub-command takes a line number and will remove what's on that line in the crontab, regardless of what that is. The number is passed, unsanitized, directly tosed
.The crontab entry, when you add one, has to be quoted. This affects how you must handle quotes inside the crontab entry itself.
It uses
crontab.tmp
as a file name to store a temporary file in the current directory, regardless of whether that file already exists or not (it will be removed).
Most of those things should be relatively easy for you to fix.
#!/bin/sh
usage () {
cat <<USAGE_END
Usage:
$0 add "job-spec"
$0 list
$0 remove "job-spec-lineno"
USAGE_END
}
if [ -z "$1" ]; then
usage >&2
exit 1
fi
case "$1" in
add)
if [ -z "$2" ]; then
usage >&2
exit 1
fi
crontab -l >crontab.tmp
printf '%sn' "$2" >>crontab.tmp
crontab crontab.tmp && rm -f crontab.tmp
;;
list)
crontab -l | cat -n
;;
remove)
if [ -z "$2" ]; then
usage >&2
exit 1
fi
crontab -l | sed -e "$2d" >crontab.tmp
crontab crontab.tmp && rm -f crontab.tmp
;;
*)
usage >&2
exit 1
;;
esac
To use:
$ ./script
Usage:
./script add "job-spec"
./script list
./script remove "job-spec-lineno"
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
$ ./script add "0 15 * * * echo 'hello world!'"
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
4 0 15 * * * echo 'hello world!'
$ ./script remove 4
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
Surely this would work, but I'm not asking how to add jobs at the last line and/or pick ones from all cron jobs and remove them. This may possibly collide with the other softwares (if they handle cron jobs poorly), and the users who deals with crontab frequently will end up with an ugly crontab file. I expected, for example, a folder per user which cron reads all the crontab files inside it and runs, so that I can make a separate crontab file for my script.
– queued
May 6 '17 at 16:18
A nice example: GNOME's startup application works this way! It reads all scripts from ~/.config/autostart/. However, I found that there are so many things from Linux that share this kind of "philosophy" of crontab. I'm so confused now. Thanks for the script anyway. Maybe I'm going to use it.
– queued
May 6 '17 at 16:20
@queued cron manages the tabs in exactly the way you describe (only one file per user though, by design). Have a look in/var/cron/tabs
(it may be a different folder on your system). This is not to be modified through other means than by thecrontab
command though, so anything you build will have to use that. You could obviously also have a system where you have multiple crontabs per user, but you would need to concatenate these to have them activated by cron.
– Kusalananda
May 6 '17 at 16:24
My point is: I don't get the design that allows only one file per user. Is it intended, by some acceptable reasons?
– queued
May 6 '17 at 16:44
1
Now I got the point. I misinterpreted the program cron as the only way to run programs periodically, though it actually was just one of the programs that does the thing with a simple interface. I think I should make another program that periodically runs programs, or simply make a folder and make a cron job torun-parts
it as you mentioned.
– queued
May 6 '17 at 17:32
|
show 1 more comment
up vote
1
down vote
Your current cron implementation probably supports /etc/cron.d, where jobs have an additional "run as" user specified after the regular time fields and before the command. So, just adjust your interface to create files in that directory like regular cron entries with the username (perhaps extracted from the loginuid) prepended after the fifth field. Then you can do one job per file. :)
Look at man 5 crontab
https://linux.die.net/man/5/crontab
Note that the main problem with this is that a user who can edit files in that directory could create a file which runs as root. So, you probably want a wrapper script run via sudo which will validate the input and force the calculated username into the generated file. And then got need to make sure you're doing things securely within the script, like not trusting $PATH, etc.
PS, in a shell script: getent passwd $(</proc/self/loginuid)
Honestly, if you're making users know the cron time format, a few extra seconds to teach them to use crontab -e
(and set $EDITOR
if vi is scary) isn't terribly difficult.
add a comment |
up vote
0
down vote
If you want a cron entry:
0 * * * * my_script
then I recommend you think of a separate name for your cron management function, like, "cron_mgmt", whose first argument is a SWITCH in a CASE statement:
cron_mgmt () {
case $1 in
add ) ... ;;
list ) ...;;
remove ) ...
help ) ...
* ) echo "You need help. Here it is"
cron_mgmt help
;;
esac
}
add a comment |
up vote
0
down vote
Rather than roll your own interface, keep it simple. To install a cron job with a certain schedule, place it in a certain directory. To remove it, remove it from the directory. You don't need to provide users with any tools to do that, just tell them which directory to put their job in.
This is how most Linux distributions manage system cron jobs that can be installed by individual packages. Debian, Fedora, Arch Linux and others ship a tool called run-parts
whose job is to run the scripts in a particular directory one by one. The different implementations of run-parts
have different rules on exactly which file names are acceptable for scripts. If you don't want to depend on this, you can roll your own:
for x in /path/to/daily-jobs/*; do
if [ -x "$x" ]; then
case "${x##*/}" in
*[!-0-9A-Z_a-z]*) :;; # skip file names containing "weird" characters
*) "$x";;
esac
fi
done
If you want to allow users to specify their own schedule, then this approach won't work. You need to rebuild the crontab file each time a new job is submitted. This can be done, but is complicated to set up reliably. However, if users can specify their own schedule, then there's little reason to add another interface on top of crontab -e
, or a GUI that calls crontab -e
under the hood.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f363376%2fhow-do-i-add-remove-cron-jobs-by-script%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
6
down vote
accepted
Using cron is the correct way to schedule periodic running of tasks on most Unix systems. Using a personal crontab is the most convenient way for a user to schedule their own tasks. System tasks may be scheduled by root (not using the script below!) in the system crontab, which usually has an ever so slightly different format (an extra user field).
Here's a simple script for you. Any user may use this to manage their own personal crontab.
It doesn't do any type of validation of its input except that it will complain if you give it too few arguments. It is therefore completely possible to add improperly formatted crontab entries.
The
remove
sub-command takes a line number and will remove what's on that line in the crontab, regardless of what that is. The number is passed, unsanitized, directly tosed
.The crontab entry, when you add one, has to be quoted. This affects how you must handle quotes inside the crontab entry itself.
It uses
crontab.tmp
as a file name to store a temporary file in the current directory, regardless of whether that file already exists or not (it will be removed).
Most of those things should be relatively easy for you to fix.
#!/bin/sh
usage () {
cat <<USAGE_END
Usage:
$0 add "job-spec"
$0 list
$0 remove "job-spec-lineno"
USAGE_END
}
if [ -z "$1" ]; then
usage >&2
exit 1
fi
case "$1" in
add)
if [ -z "$2" ]; then
usage >&2
exit 1
fi
crontab -l >crontab.tmp
printf '%sn' "$2" >>crontab.tmp
crontab crontab.tmp && rm -f crontab.tmp
;;
list)
crontab -l | cat -n
;;
remove)
if [ -z "$2" ]; then
usage >&2
exit 1
fi
crontab -l | sed -e "$2d" >crontab.tmp
crontab crontab.tmp && rm -f crontab.tmp
;;
*)
usage >&2
exit 1
;;
esac
To use:
$ ./script
Usage:
./script add "job-spec"
./script list
./script remove "job-spec-lineno"
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
$ ./script add "0 15 * * * echo 'hello world!'"
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
4 0 15 * * * echo 'hello world!'
$ ./script remove 4
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
Surely this would work, but I'm not asking how to add jobs at the last line and/or pick ones from all cron jobs and remove them. This may possibly collide with the other softwares (if they handle cron jobs poorly), and the users who deals with crontab frequently will end up with an ugly crontab file. I expected, for example, a folder per user which cron reads all the crontab files inside it and runs, so that I can make a separate crontab file for my script.
– queued
May 6 '17 at 16:18
A nice example: GNOME's startup application works this way! It reads all scripts from ~/.config/autostart/. However, I found that there are so many things from Linux that share this kind of "philosophy" of crontab. I'm so confused now. Thanks for the script anyway. Maybe I'm going to use it.
– queued
May 6 '17 at 16:20
@queued cron manages the tabs in exactly the way you describe (only one file per user though, by design). Have a look in/var/cron/tabs
(it may be a different folder on your system). This is not to be modified through other means than by thecrontab
command though, so anything you build will have to use that. You could obviously also have a system where you have multiple crontabs per user, but you would need to concatenate these to have them activated by cron.
– Kusalananda
May 6 '17 at 16:24
My point is: I don't get the design that allows only one file per user. Is it intended, by some acceptable reasons?
– queued
May 6 '17 at 16:44
1
Now I got the point. I misinterpreted the program cron as the only way to run programs periodically, though it actually was just one of the programs that does the thing with a simple interface. I think I should make another program that periodically runs programs, or simply make a folder and make a cron job torun-parts
it as you mentioned.
– queued
May 6 '17 at 17:32
|
show 1 more comment
up vote
6
down vote
accepted
Using cron is the correct way to schedule periodic running of tasks on most Unix systems. Using a personal crontab is the most convenient way for a user to schedule their own tasks. System tasks may be scheduled by root (not using the script below!) in the system crontab, which usually has an ever so slightly different format (an extra user field).
Here's a simple script for you. Any user may use this to manage their own personal crontab.
It doesn't do any type of validation of its input except that it will complain if you give it too few arguments. It is therefore completely possible to add improperly formatted crontab entries.
The
remove
sub-command takes a line number and will remove what's on that line in the crontab, regardless of what that is. The number is passed, unsanitized, directly tosed
.The crontab entry, when you add one, has to be quoted. This affects how you must handle quotes inside the crontab entry itself.
It uses
crontab.tmp
as a file name to store a temporary file in the current directory, regardless of whether that file already exists or not (it will be removed).
Most of those things should be relatively easy for you to fix.
#!/bin/sh
usage () {
cat <<USAGE_END
Usage:
$0 add "job-spec"
$0 list
$0 remove "job-spec-lineno"
USAGE_END
}
if [ -z "$1" ]; then
usage >&2
exit 1
fi
case "$1" in
add)
if [ -z "$2" ]; then
usage >&2
exit 1
fi
crontab -l >crontab.tmp
printf '%sn' "$2" >>crontab.tmp
crontab crontab.tmp && rm -f crontab.tmp
;;
list)
crontab -l | cat -n
;;
remove)
if [ -z "$2" ]; then
usage >&2
exit 1
fi
crontab -l | sed -e "$2d" >crontab.tmp
crontab crontab.tmp && rm -f crontab.tmp
;;
*)
usage >&2
exit 1
;;
esac
To use:
$ ./script
Usage:
./script add "job-spec"
./script list
./script remove "job-spec-lineno"
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
$ ./script add "0 15 * * * echo 'hello world!'"
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
4 0 15 * * * echo 'hello world!'
$ ./script remove 4
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
Surely this would work, but I'm not asking how to add jobs at the last line and/or pick ones from all cron jobs and remove them. This may possibly collide with the other softwares (if they handle cron jobs poorly), and the users who deals with crontab frequently will end up with an ugly crontab file. I expected, for example, a folder per user which cron reads all the crontab files inside it and runs, so that I can make a separate crontab file for my script.
– queued
May 6 '17 at 16:18
A nice example: GNOME's startup application works this way! It reads all scripts from ~/.config/autostart/. However, I found that there are so many things from Linux that share this kind of "philosophy" of crontab. I'm so confused now. Thanks for the script anyway. Maybe I'm going to use it.
– queued
May 6 '17 at 16:20
@queued cron manages the tabs in exactly the way you describe (only one file per user though, by design). Have a look in/var/cron/tabs
(it may be a different folder on your system). This is not to be modified through other means than by thecrontab
command though, so anything you build will have to use that. You could obviously also have a system where you have multiple crontabs per user, but you would need to concatenate these to have them activated by cron.
– Kusalananda
May 6 '17 at 16:24
My point is: I don't get the design that allows only one file per user. Is it intended, by some acceptable reasons?
– queued
May 6 '17 at 16:44
1
Now I got the point. I misinterpreted the program cron as the only way to run programs periodically, though it actually was just one of the programs that does the thing with a simple interface. I think I should make another program that periodically runs programs, or simply make a folder and make a cron job torun-parts
it as you mentioned.
– queued
May 6 '17 at 17:32
|
show 1 more comment
up vote
6
down vote
accepted
up vote
6
down vote
accepted
Using cron is the correct way to schedule periodic running of tasks on most Unix systems. Using a personal crontab is the most convenient way for a user to schedule their own tasks. System tasks may be scheduled by root (not using the script below!) in the system crontab, which usually has an ever so slightly different format (an extra user field).
Here's a simple script for you. Any user may use this to manage their own personal crontab.
It doesn't do any type of validation of its input except that it will complain if you give it too few arguments. It is therefore completely possible to add improperly formatted crontab entries.
The
remove
sub-command takes a line number and will remove what's on that line in the crontab, regardless of what that is. The number is passed, unsanitized, directly tosed
.The crontab entry, when you add one, has to be quoted. This affects how you must handle quotes inside the crontab entry itself.
It uses
crontab.tmp
as a file name to store a temporary file in the current directory, regardless of whether that file already exists or not (it will be removed).
Most of those things should be relatively easy for you to fix.
#!/bin/sh
usage () {
cat <<USAGE_END
Usage:
$0 add "job-spec"
$0 list
$0 remove "job-spec-lineno"
USAGE_END
}
if [ -z "$1" ]; then
usage >&2
exit 1
fi
case "$1" in
add)
if [ -z "$2" ]; then
usage >&2
exit 1
fi
crontab -l >crontab.tmp
printf '%sn' "$2" >>crontab.tmp
crontab crontab.tmp && rm -f crontab.tmp
;;
list)
crontab -l | cat -n
;;
remove)
if [ -z "$2" ]; then
usage >&2
exit 1
fi
crontab -l | sed -e "$2d" >crontab.tmp
crontab crontab.tmp && rm -f crontab.tmp
;;
*)
usage >&2
exit 1
;;
esac
To use:
$ ./script
Usage:
./script add "job-spec"
./script list
./script remove "job-spec-lineno"
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
$ ./script add "0 15 * * * echo 'hello world!'"
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
4 0 15 * * * echo 'hello world!'
$ ./script remove 4
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
Using cron is the correct way to schedule periodic running of tasks on most Unix systems. Using a personal crontab is the most convenient way for a user to schedule their own tasks. System tasks may be scheduled by root (not using the script below!) in the system crontab, which usually has an ever so slightly different format (an extra user field).
Here's a simple script for you. Any user may use this to manage their own personal crontab.
It doesn't do any type of validation of its input except that it will complain if you give it too few arguments. It is therefore completely possible to add improperly formatted crontab entries.
The
remove
sub-command takes a line number and will remove what's on that line in the crontab, regardless of what that is. The number is passed, unsanitized, directly tosed
.The crontab entry, when you add one, has to be quoted. This affects how you must handle quotes inside the crontab entry itself.
It uses
crontab.tmp
as a file name to store a temporary file in the current directory, regardless of whether that file already exists or not (it will be removed).
Most of those things should be relatively easy for you to fix.
#!/bin/sh
usage () {
cat <<USAGE_END
Usage:
$0 add "job-spec"
$0 list
$0 remove "job-spec-lineno"
USAGE_END
}
if [ -z "$1" ]; then
usage >&2
exit 1
fi
case "$1" in
add)
if [ -z "$2" ]; then
usage >&2
exit 1
fi
crontab -l >crontab.tmp
printf '%sn' "$2" >>crontab.tmp
crontab crontab.tmp && rm -f crontab.tmp
;;
list)
crontab -l | cat -n
;;
remove)
if [ -z "$2" ]; then
usage >&2
exit 1
fi
crontab -l | sed -e "$2d" >crontab.tmp
crontab crontab.tmp && rm -f crontab.tmp
;;
*)
usage >&2
exit 1
;;
esac
To use:
$ ./script
Usage:
./script add "job-spec"
./script list
./script remove "job-spec-lineno"
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
$ ./script add "0 15 * * * echo 'hello world!'"
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
4 0 15 * * * echo 'hello world!'
$ ./script remove 4
$ ./script list
1 */15 * * * * /bin/date >>"$HOME"/.fetchmail.log
2 @hourly /usr/bin/newsyslog -r -f "$HOME/.newsyslog.conf"
3 @reboot /usr/local/bin/fetchmail
edited yesterday
answered May 6 '17 at 15:03
Kusalananda
120k16225369
120k16225369
Surely this would work, but I'm not asking how to add jobs at the last line and/or pick ones from all cron jobs and remove them. This may possibly collide with the other softwares (if they handle cron jobs poorly), and the users who deals with crontab frequently will end up with an ugly crontab file. I expected, for example, a folder per user which cron reads all the crontab files inside it and runs, so that I can make a separate crontab file for my script.
– queued
May 6 '17 at 16:18
A nice example: GNOME's startup application works this way! It reads all scripts from ~/.config/autostart/. However, I found that there are so many things from Linux that share this kind of "philosophy" of crontab. I'm so confused now. Thanks for the script anyway. Maybe I'm going to use it.
– queued
May 6 '17 at 16:20
@queued cron manages the tabs in exactly the way you describe (only one file per user though, by design). Have a look in/var/cron/tabs
(it may be a different folder on your system). This is not to be modified through other means than by thecrontab
command though, so anything you build will have to use that. You could obviously also have a system where you have multiple crontabs per user, but you would need to concatenate these to have them activated by cron.
– Kusalananda
May 6 '17 at 16:24
My point is: I don't get the design that allows only one file per user. Is it intended, by some acceptable reasons?
– queued
May 6 '17 at 16:44
1
Now I got the point. I misinterpreted the program cron as the only way to run programs periodically, though it actually was just one of the programs that does the thing with a simple interface. I think I should make another program that periodically runs programs, or simply make a folder and make a cron job torun-parts
it as you mentioned.
– queued
May 6 '17 at 17:32
|
show 1 more comment
Surely this would work, but I'm not asking how to add jobs at the last line and/or pick ones from all cron jobs and remove them. This may possibly collide with the other softwares (if they handle cron jobs poorly), and the users who deals with crontab frequently will end up with an ugly crontab file. I expected, for example, a folder per user which cron reads all the crontab files inside it and runs, so that I can make a separate crontab file for my script.
– queued
May 6 '17 at 16:18
A nice example: GNOME's startup application works this way! It reads all scripts from ~/.config/autostart/. However, I found that there are so many things from Linux that share this kind of "philosophy" of crontab. I'm so confused now. Thanks for the script anyway. Maybe I'm going to use it.
– queued
May 6 '17 at 16:20
@queued cron manages the tabs in exactly the way you describe (only one file per user though, by design). Have a look in/var/cron/tabs
(it may be a different folder on your system). This is not to be modified through other means than by thecrontab
command though, so anything you build will have to use that. You could obviously also have a system where you have multiple crontabs per user, but you would need to concatenate these to have them activated by cron.
– Kusalananda
May 6 '17 at 16:24
My point is: I don't get the design that allows only one file per user. Is it intended, by some acceptable reasons?
– queued
May 6 '17 at 16:44
1
Now I got the point. I misinterpreted the program cron as the only way to run programs periodically, though it actually was just one of the programs that does the thing with a simple interface. I think I should make another program that periodically runs programs, or simply make a folder and make a cron job torun-parts
it as you mentioned.
– queued
May 6 '17 at 17:32
Surely this would work, but I'm not asking how to add jobs at the last line and/or pick ones from all cron jobs and remove them. This may possibly collide with the other softwares (if they handle cron jobs poorly), and the users who deals with crontab frequently will end up with an ugly crontab file. I expected, for example, a folder per user which cron reads all the crontab files inside it and runs, so that I can make a separate crontab file for my script.
– queued
May 6 '17 at 16:18
Surely this would work, but I'm not asking how to add jobs at the last line and/or pick ones from all cron jobs and remove them. This may possibly collide with the other softwares (if they handle cron jobs poorly), and the users who deals with crontab frequently will end up with an ugly crontab file. I expected, for example, a folder per user which cron reads all the crontab files inside it and runs, so that I can make a separate crontab file for my script.
– queued
May 6 '17 at 16:18
A nice example: GNOME's startup application works this way! It reads all scripts from ~/.config/autostart/. However, I found that there are so many things from Linux that share this kind of "philosophy" of crontab. I'm so confused now. Thanks for the script anyway. Maybe I'm going to use it.
– queued
May 6 '17 at 16:20
A nice example: GNOME's startup application works this way! It reads all scripts from ~/.config/autostart/. However, I found that there are so many things from Linux that share this kind of "philosophy" of crontab. I'm so confused now. Thanks for the script anyway. Maybe I'm going to use it.
– queued
May 6 '17 at 16:20
@queued cron manages the tabs in exactly the way you describe (only one file per user though, by design). Have a look in
/var/cron/tabs
(it may be a different folder on your system). This is not to be modified through other means than by the crontab
command though, so anything you build will have to use that. You could obviously also have a system where you have multiple crontabs per user, but you would need to concatenate these to have them activated by cron.– Kusalananda
May 6 '17 at 16:24
@queued cron manages the tabs in exactly the way you describe (only one file per user though, by design). Have a look in
/var/cron/tabs
(it may be a different folder on your system). This is not to be modified through other means than by the crontab
command though, so anything you build will have to use that. You could obviously also have a system where you have multiple crontabs per user, but you would need to concatenate these to have them activated by cron.– Kusalananda
May 6 '17 at 16:24
My point is: I don't get the design that allows only one file per user. Is it intended, by some acceptable reasons?
– queued
May 6 '17 at 16:44
My point is: I don't get the design that allows only one file per user. Is it intended, by some acceptable reasons?
– queued
May 6 '17 at 16:44
1
1
Now I got the point. I misinterpreted the program cron as the only way to run programs periodically, though it actually was just one of the programs that does the thing with a simple interface. I think I should make another program that periodically runs programs, or simply make a folder and make a cron job to
run-parts
it as you mentioned.– queued
May 6 '17 at 17:32
Now I got the point. I misinterpreted the program cron as the only way to run programs periodically, though it actually was just one of the programs that does the thing with a simple interface. I think I should make another program that periodically runs programs, or simply make a folder and make a cron job to
run-parts
it as you mentioned.– queued
May 6 '17 at 17:32
|
show 1 more comment
up vote
1
down vote
Your current cron implementation probably supports /etc/cron.d, where jobs have an additional "run as" user specified after the regular time fields and before the command. So, just adjust your interface to create files in that directory like regular cron entries with the username (perhaps extracted from the loginuid) prepended after the fifth field. Then you can do one job per file. :)
Look at man 5 crontab
https://linux.die.net/man/5/crontab
Note that the main problem with this is that a user who can edit files in that directory could create a file which runs as root. So, you probably want a wrapper script run via sudo which will validate the input and force the calculated username into the generated file. And then got need to make sure you're doing things securely within the script, like not trusting $PATH, etc.
PS, in a shell script: getent passwd $(</proc/self/loginuid)
Honestly, if you're making users know the cron time format, a few extra seconds to teach them to use crontab -e
(and set $EDITOR
if vi is scary) isn't terribly difficult.
add a comment |
up vote
1
down vote
Your current cron implementation probably supports /etc/cron.d, where jobs have an additional "run as" user specified after the regular time fields and before the command. So, just adjust your interface to create files in that directory like regular cron entries with the username (perhaps extracted from the loginuid) prepended after the fifth field. Then you can do one job per file. :)
Look at man 5 crontab
https://linux.die.net/man/5/crontab
Note that the main problem with this is that a user who can edit files in that directory could create a file which runs as root. So, you probably want a wrapper script run via sudo which will validate the input and force the calculated username into the generated file. And then got need to make sure you're doing things securely within the script, like not trusting $PATH, etc.
PS, in a shell script: getent passwd $(</proc/self/loginuid)
Honestly, if you're making users know the cron time format, a few extra seconds to teach them to use crontab -e
(and set $EDITOR
if vi is scary) isn't terribly difficult.
add a comment |
up vote
1
down vote
up vote
1
down vote
Your current cron implementation probably supports /etc/cron.d, where jobs have an additional "run as" user specified after the regular time fields and before the command. So, just adjust your interface to create files in that directory like regular cron entries with the username (perhaps extracted from the loginuid) prepended after the fifth field. Then you can do one job per file. :)
Look at man 5 crontab
https://linux.die.net/man/5/crontab
Note that the main problem with this is that a user who can edit files in that directory could create a file which runs as root. So, you probably want a wrapper script run via sudo which will validate the input and force the calculated username into the generated file. And then got need to make sure you're doing things securely within the script, like not trusting $PATH, etc.
PS, in a shell script: getent passwd $(</proc/self/loginuid)
Honestly, if you're making users know the cron time format, a few extra seconds to teach them to use crontab -e
(and set $EDITOR
if vi is scary) isn't terribly difficult.
Your current cron implementation probably supports /etc/cron.d, where jobs have an additional "run as" user specified after the regular time fields and before the command. So, just adjust your interface to create files in that directory like regular cron entries with the username (perhaps extracted from the loginuid) prepended after the fifth field. Then you can do one job per file. :)
Look at man 5 crontab
https://linux.die.net/man/5/crontab
Note that the main problem with this is that a user who can edit files in that directory could create a file which runs as root. So, you probably want a wrapper script run via sudo which will validate the input and force the calculated username into the generated file. And then got need to make sure you're doing things securely within the script, like not trusting $PATH, etc.
PS, in a shell script: getent passwd $(</proc/self/loginuid)
Honestly, if you're making users know the cron time format, a few extra seconds to teach them to use crontab -e
(and set $EDITOR
if vi is scary) isn't terribly difficult.
edited May 6 '17 at 22:55
answered May 6 '17 at 22:50
dannysauer
82748
82748
add a comment |
add a comment |
up vote
0
down vote
If you want a cron entry:
0 * * * * my_script
then I recommend you think of a separate name for your cron management function, like, "cron_mgmt", whose first argument is a SWITCH in a CASE statement:
cron_mgmt () {
case $1 in
add ) ... ;;
list ) ...;;
remove ) ...
help ) ...
* ) echo "You need help. Here it is"
cron_mgmt help
;;
esac
}
add a comment |
up vote
0
down vote
If you want a cron entry:
0 * * * * my_script
then I recommend you think of a separate name for your cron management function, like, "cron_mgmt", whose first argument is a SWITCH in a CASE statement:
cron_mgmt () {
case $1 in
add ) ... ;;
list ) ...;;
remove ) ...
help ) ...
* ) echo "You need help. Here it is"
cron_mgmt help
;;
esac
}
add a comment |
up vote
0
down vote
up vote
0
down vote
If you want a cron entry:
0 * * * * my_script
then I recommend you think of a separate name for your cron management function, like, "cron_mgmt", whose first argument is a SWITCH in a CASE statement:
cron_mgmt () {
case $1 in
add ) ... ;;
list ) ...;;
remove ) ...
help ) ...
* ) echo "You need help. Here it is"
cron_mgmt help
;;
esac
}
If you want a cron entry:
0 * * * * my_script
then I recommend you think of a separate name for your cron management function, like, "cron_mgmt", whose first argument is a SWITCH in a CASE statement:
cron_mgmt () {
case $1 in
add ) ... ;;
list ) ...;;
remove ) ...
help ) ...
* ) echo "You need help. Here it is"
cron_mgmt help
;;
esac
}
edited May 6 '17 at 15:08
Stephen Rauch
3,318101328
3,318101328
answered May 6 '17 at 14:58
Marty McGowan
1292
1292
add a comment |
add a comment |
up vote
0
down vote
Rather than roll your own interface, keep it simple. To install a cron job with a certain schedule, place it in a certain directory. To remove it, remove it from the directory. You don't need to provide users with any tools to do that, just tell them which directory to put their job in.
This is how most Linux distributions manage system cron jobs that can be installed by individual packages. Debian, Fedora, Arch Linux and others ship a tool called run-parts
whose job is to run the scripts in a particular directory one by one. The different implementations of run-parts
have different rules on exactly which file names are acceptable for scripts. If you don't want to depend on this, you can roll your own:
for x in /path/to/daily-jobs/*; do
if [ -x "$x" ]; then
case "${x##*/}" in
*[!-0-9A-Z_a-z]*) :;; # skip file names containing "weird" characters
*) "$x";;
esac
fi
done
If you want to allow users to specify their own schedule, then this approach won't work. You need to rebuild the crontab file each time a new job is submitted. This can be done, but is complicated to set up reliably. However, if users can specify their own schedule, then there's little reason to add another interface on top of crontab -e
, or a GUI that calls crontab -e
under the hood.
add a comment |
up vote
0
down vote
Rather than roll your own interface, keep it simple. To install a cron job with a certain schedule, place it in a certain directory. To remove it, remove it from the directory. You don't need to provide users with any tools to do that, just tell them which directory to put their job in.
This is how most Linux distributions manage system cron jobs that can be installed by individual packages. Debian, Fedora, Arch Linux and others ship a tool called run-parts
whose job is to run the scripts in a particular directory one by one. The different implementations of run-parts
have different rules on exactly which file names are acceptable for scripts. If you don't want to depend on this, you can roll your own:
for x in /path/to/daily-jobs/*; do
if [ -x "$x" ]; then
case "${x##*/}" in
*[!-0-9A-Z_a-z]*) :;; # skip file names containing "weird" characters
*) "$x";;
esac
fi
done
If you want to allow users to specify their own schedule, then this approach won't work. You need to rebuild the crontab file each time a new job is submitted. This can be done, but is complicated to set up reliably. However, if users can specify their own schedule, then there's little reason to add another interface on top of crontab -e
, or a GUI that calls crontab -e
under the hood.
add a comment |
up vote
0
down vote
up vote
0
down vote
Rather than roll your own interface, keep it simple. To install a cron job with a certain schedule, place it in a certain directory. To remove it, remove it from the directory. You don't need to provide users with any tools to do that, just tell them which directory to put their job in.
This is how most Linux distributions manage system cron jobs that can be installed by individual packages. Debian, Fedora, Arch Linux and others ship a tool called run-parts
whose job is to run the scripts in a particular directory one by one. The different implementations of run-parts
have different rules on exactly which file names are acceptable for scripts. If you don't want to depend on this, you can roll your own:
for x in /path/to/daily-jobs/*; do
if [ -x "$x" ]; then
case "${x##*/}" in
*[!-0-9A-Z_a-z]*) :;; # skip file names containing "weird" characters
*) "$x";;
esac
fi
done
If you want to allow users to specify their own schedule, then this approach won't work. You need to rebuild the crontab file each time a new job is submitted. This can be done, but is complicated to set up reliably. However, if users can specify their own schedule, then there's little reason to add another interface on top of crontab -e
, or a GUI that calls crontab -e
under the hood.
Rather than roll your own interface, keep it simple. To install a cron job with a certain schedule, place it in a certain directory. To remove it, remove it from the directory. You don't need to provide users with any tools to do that, just tell them which directory to put their job in.
This is how most Linux distributions manage system cron jobs that can be installed by individual packages. Debian, Fedora, Arch Linux and others ship a tool called run-parts
whose job is to run the scripts in a particular directory one by one. The different implementations of run-parts
have different rules on exactly which file names are acceptable for scripts. If you don't want to depend on this, you can roll your own:
for x in /path/to/daily-jobs/*; do
if [ -x "$x" ]; then
case "${x##*/}" in
*[!-0-9A-Z_a-z]*) :;; # skip file names containing "weird" characters
*) "$x";;
esac
fi
done
If you want to allow users to specify their own schedule, then this approach won't work. You need to rebuild the crontab file each time a new job is submitted. This can be done, but is complicated to set up reliably. However, if users can specify their own schedule, then there's little reason to add another interface on top of crontab -e
, or a GUI that calls crontab -e
under the hood.
answered May 6 '17 at 22:30
Gilles
525k12710511578
525k12710511578
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f363376%2fhow-do-i-add-remove-cron-jobs-by-script%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown