- How To Run A Command Or Script As Root On Startup / Boot Using systemd or A Cron Job
- How to use systemd to run a command or script as root on boot
- How to use a cron job to run a command or script as root on startup / boot
- cron: Run .sh as root
- 1 Answer 1
- Assumptions:
- Ensure Sudoers allows the script call
- Try this:
- Is it possible to make a Bash file run as root in crontab? [closed]
- 6 Answers 6
- How to set up a root cron job properly
How To Run A Command Or Script As Root On Startup / Boot Using systemd or A Cron Job
How to use systemd to run a command or script as root on boot
To use systemd to run a command or script as root when your computer boots, create a file (as root) called mycommand.service (replace mycommand with whatever you want to call it) in /etc/systemd/system/ .
We can use Nano command line text editor to open / create this file:
sudo nano /etc/systemd/system/mycommand.service
In this file, paste the following:
[Unit]Description=your description
[Service]ExecStart=/path/to/command/or/script
[Install]
WantedBy=multi-user.target
Here, change the Description value to describe what this does, and the ExecStart value to the command or path of the script you want to run as root on startup. Don’t add sudo at the beginning of the command or script, because it runs as root anyway.
Now save the file and exit Nano. In case you’re not familiar with Nano text editor, you can save the file by pressing Ctrl + o , then Enter . Exit by pressing Ctrl + x .
Next, you need to enable the systemd service to run on boot, using the following command:
sudo systemctl enable mycommand.service
Remember to replace mycommand.service with the actual filename you’ve used for this systemd service file. There’s no need to run the systemd service right now, since this is about running it on boot.
If you use this to run a script, make sure to make the script executable ( chmod +x /path/to/script ) or else it won’t run.
This is a very simple systemd unit file that runs only once. These can be a lot more complex, depending on what you need. For example, you could use a command that runs before ExecStart , have it start only after another unit becomes active, have the command run only after another service, e.g. the network service has been started ( After=network.target , while also declaring a dependency to this service using Wants= or Requires= ), and more. Check out the systemd.service and systemd.unit man pages for more details.
How to use a cron job to run a command or script as root on startup / boot
To use a cron job to run a command or script as root when the system boots, edit the root user crontab using:
And at the bottom of the file (it may also be empty), use the following:
@reboot /path/to/command/or/script
Now save the crontab and exit. If you’ve used Nano command line editor to edit it (should be default in most cases), you can save the file by pressing Ctrl + o , then Enter . Exit Nano by pressing Ctrl + x . Don’t add sudo before command or script, because it runs as root anyway, since it’s added to the root crontab.
In case you want to use a particular editor to edit the root crontab, run it like this: sudo EDITOR=editor crontab -e , e.g. for Vim: sudo EDITOR=vim crontab -e , or for Nano: sudo EDITOR=nano crontab -e .
- If you use this to run a script, make sure to make the script executable ( chmod +x /path/to/script ) or else it won’t run
- Use the full path to the command or script, or else it may fail to run (this depends on the Linux distribution you’re using, e.g. you don’t need to use the full path on Ubuntu 20.04 for example)
- If the script ran by cron also includes commands without the full path, you can avoid having to rewrite the script by adding this at the top of the crontab file: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- If you need to delay the start of the command / script, you can make use of the sleep command, e.g.: @reboot /usr/bin/sleep 60; /path/to/command/or/script to run the command or script 60 seconds after the system boots
Which to choose between systemd or a cron job to run a command or script as root on startup / boot, if you have a choice? When in doubt, pick systemd (if it’s available on your system) because it should be more reliable and easier to use.
For example, not every version of cron supports the @reboot option, or the command / script may only run when the system is rebooted, and not when it’s shut down (this didn’t happen for me on Ubuntu 20.04, Fedora 24, Manjaro Linux and Debian 10, but it may happen on some Linux distributions).
It’s also worth noting that @reboot configures a job to run once when the daemon is started. cron is not usually restarted, so this usually corresponds to the machine being booted. For example, Debian (and Debian-based Linux distributions) enforces this, making cron not re-run @reboot jobs when the cron service is restarted. On some Linux distributions, though, restarting the cron service may re-run the @reboot commands.
Also, on Fedora, cron is not installed by default (install it using sudo dnf install cronie ). On Manjaro, cron is installed by default, but not enabled by default (enable it using sudo systemctl enable —now cronie ).
cron: Run .sh as root
To make things clear first: I’m using a virtual machine which is offline — security is therefor no showstopper for my need. I have a simple bash script which performs which uses wmctrl to gracefully closes a process. KILL is not an option:
* * * * * sudo wmctrl -xc notepadqq-bin.Notepadqq * * * * * /bin/echo "works" >> /home/usr/cron.log
I tried sudo crontab -e as well as crontab -e , the cron.log is written every minute, however the wmctrl command is not working. I even tried to echo «password» | sudo -S rm somefile but this doesnt work for me either. TIA!
If security isn’t much of an issue, can you edit sudoers to allow you to run the commands you need as root without the password prompt?
SO is for programming questions, not questions about using or configuring Linux and its applications. SuperUser.com or unix.stackexchange.com would be better places for questions like this.
@Barmar: Perhaps, but there are still a lot of cron questions here. One could argue that crontab uses a specialized language, and these questions are about how to program in it.
1 Answer 1
First I’m going to make some assumptions (please correct me if these are wrong and I’ll try to adapt the answer for you)
Assumptions:
- you want to use cron and not any old job manager (I think this is safe from your question)
- you are already familiar with cron and would like the cronjobs to actually run as often as possible (this seems odd to me but may not be central to the question at hand) ( Edit: I also agree with that other guy’s recommendation to look at https://stackoverflow.com/tags/cron/info as it provides more in depth discussion on the use of cron )
- you want to use sudo for root privileges and not have the cron daemon run as root (which is normal on most systems)
- you are not satisfied with chown 0:0 $(which wmctrl) the effect of chmod 4755 $(which wmctrl) or more restrictive chmod 4755 $(which wmctrl)
- the results of a cron tab line «* * * * * sudo wmctrl -d >> /home/usr/cron.log» shows this «notepadqq-bin.Notepadqq» is still active from cron’s perspective (IF THIS IS NOT THE CASE check the environment variables for wmctrl are preserved from cron’t perspective. and let me know this assumption was wrong)
- your comment «even tried to echo «password» | sudo -S rm somefile but this doesn’t work for me either.» implies you have a password for using sudo
- You mean your comment «security is therefor no showstopper for my need»
Ensure Sudoers allows the script call
Given those assumptions, I’d recommend first looking into how sudo is setup:
Try this:
(DO NOT EDIT THIS FILE WITHOUT THE visudo command you can corrupt your system) export EDITOR=vi ; sudo visudo -f /etc/sudoers
you will want a line similar to this: %sudo ALL=(ALL) NOPASSWD: ALL OR cron ALL=(ALL) NOPASSWD: ALL
given that you can be sure the issue is not a password prompt issue with sudo and that the command (infact ALL commands run via sudo ) are run as root by default (when not using -u to set to another user)
Is it possible to make a Bash file run as root in crontab? [closed]
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
[root@file nutch-0.9]# locate crontab /etc/crontab /etc/sysconfig/crontab /usr/bin/crontab /usr/share/man/man1/crontab.1.gz /usr/share/man/man1p/crontab.1p.gz /usr/share/man/man5/crontab.5.gz /usr/share/vim/vim71/syntax/crontab.vim [root@file nutch-0.9]#
6 Answers 6
Yes, just add it to the root users’ crontab; run the crontab -e command.
The places cron stores its files can be a little bizzare, so use the crontab -e command which will make sure it’s in the right place, and I believe it checks the syntax.
Instead of directly modifying a crontab file yourself, whatsisname is suggesting you use the «crontab -e» command, which will edit the correct crontab.
Just specify root as the user for the entry in /etc/crontab :
Alternatively you can also add the command to root’s personal crontab by using crontab -e as root.
The crontab file in /usr/bin is the executable that opens an editor if you type «crontab -e». The files below /usr/share/man are the manual pages you get when typing «man crontab». /usr/share/vim*/sytax/crontab.vim is special syntax highlighting for vim (activated for crontab files).
No matter what, you will need to have access to the root user account.
- you can add it to the root crontab, as suggested
- you can use sudo, as suggested
- you can use the setuid bit. The issue with the setuid bit is that it needs to be a compiled program. If it is compiled, you can «chmod 4755» and set the owner of the file to root, and it will run as root. If it is not compiled, you can write a tiny wrapper in C (or any other compiled programming language) that simply calls your script, and setuid on the wrapper, and make sure the wrapper is owned by root.
My advice? Use root crontab. It’s what it’s there for.
Also, there is no user entry in crontab as suggested by sth. the syntax is:
# .---------------- minute (0 - 59) # | .------------- hour (0 - 23) # | | .---------- day of month (1 - 31) # | | | .------- month (1 - 12) OR jan,feb,mar,apr . # | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat # | | | | | # * * * * * command to be executed
If you want to enter something in crontab as root, just login to your root account, «crontab -e» and voila. root crontab.
How to set up a root cron job properly
I tried to set up a root cron job to run a Bash script as root, to run at minute 7,37, every hour, every day of month, every month. This script is located in /usr/bin and named tunlrupdate.sh . It updates the DNS of Tunlr.
$ ls -l /usr/bin/tunlrupdate.sh -rwxr-xr-x 1 root root 2133 Sep 24 15:42 /usr/bin/tunlrupdate.sh
This Bash script is available here. When invoked the script writes what’s happening in a log located in /var/log/tunlr.log To add this root cron job I used the standard for root’s crontab
# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn 07,37 * * * * root /usr/bin/tunlrupdate.sh
A later command sudo crontab -l confirmed that the cron job has been inserted. I did reboot Ubuntu and was checking in the log file if the cron job was launched properly. However there is nothing in the logfile /var/log/tunlr.log meaning the job was never successfully launched. I did check that if I run the script from the command line
then the logfile is updated accordingly. Why is this cron job not running as planned in my system? UPDATE 1 : All the proposed solutions so far do not work. I thank Olli for a CLI to list the system log sudo grep CRON /var/log/syslog . However I did get a CRON error
CRON[13092]: (root) CMD ( [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php /maxlifetime) ! -execdir fuser -s <> 2>/dev/null \; -delete)
with the suggested PATH= insertion & use of absolute path from root for functions in the script or without this suggested solutions here. I still get this error. After some searching I pinpointed the error in the file /usr/lib/php5/maxlifetime as is explained here: Change #!/bin/sh -e —> #!/bin/sh -x Then listing the CRON error log in my system
sudo grep CRON /var/log/syslog Feb 11 18:07:01 Marius-PC CRON[14067]: (root) CMD (root /usr/bin/tunlrupdate.sh) Feb 11 18:07:01 Marius-PC CRON[14066]: (root) MAIL (mailed 1 byte of output; but got status 0x00ff, #012)
I still don’t get the bash script executing. This time no error is shown in the log. To get assurance this was not the content of the script I reduced the script to the following 3 lines:
#!/bin/bash LOGFILE=/var/log/tunlr.log echo $LOGFILE >> $LOGFILE
I still don’t get the cron job through. Nothing is written in the log file. So even may be an empty script will not run in cron ? I don’t get it. I am know trying a script reduced to these 2 lines: