139

I have a script in a folder:

/path/to/my/script.sh

I need this script to run every time the system starts (even if no one logs in to the system). What do I need to do in order to make this happen?

Eric Leschinski
  • 2,221
  • 1
  • 20
  • 24
Rusty
  • 1,541

5 Answers5

161

You will need root privileges for any the following. To get root, open a terminal and run the command

sudo -i

and the command prompt will change to '#' indicating that the terminal session has root privileges.

Alternative #1: Add commands to /etc/rc.local

vi /etc/rc.local

with content like the following:

# This script is executed at the end of each multiuser runlevel
/path/to/my/script.sh || exit 1   # Added by me
exit 0

Alternative #2: Add an Upstart job (for systems older than 15.04) (not recommended)

Create /etc/init/myjob.conf

vi /etc/init/myjob.conf

with content like the following

description     "my job"
start on startup
task
exec /path/to/my/script.sh

Official statement from upstart website -> "Project is in maintaince mode only. No new features are being developed and the general advice would be to move over to another minimal init system or systemd."

Alternative #3: Add an init script (obsolete)

Create a new script in /etc/init.d/myscript.

vi /etc/init.d/myscript

(Obviously it doesn't have to be called "myscript".) In this script, do whatever you want to do. Perhaps just run the script you mentioned.

#!/bin/sh
/path/to/my/script.sh

Make it executable.

chmod ugo+x /etc/init.d/myscript

Configure the init system to run this script at startup.

update-rc.d myscript defaults
jdthood
  • 12,467
  • 2
    Shouldn't people be using upstart now? – eduardocereto Dec 12 '12 at 15:14
  • It is possible to do the same thing by writing a short Upstart job. Initscripts are still supported, however, and are easy to use. – jdthood Dec 12 '12 at 15:50
  • 2
    Just added the Upstart-job method as a third alternative. – jdthood Dec 12 '12 at 15:58
  • inittab is another method (but maybe more for daemons than scripts). – Geremia Sep 09 '16 at 14:30
  • Ubuntu 16.04 now uses systemd. As per http://askubuntu.com/questions/765120/after-upgrade-to-16-04-lts-rc-local-not-executing-command one can use sudo systemctl enable rc-local.service to get /etc/rc.local compatibility or see http://unix.stackexchange.com/questions/47695/how-to-write-startup-script-for-systemd for systemd native script (but /etc/rc.local has the benefit of a lot of simplicity). Maybe add "Alternative #4. Add an systemd job" here? – djb Sep 12 '16 at 21:07
  • on alternative 2, don't forget to add the command sh before the script: "sh /path/to/my/script.sh" I was lazy enough to not even read the command! lol – Rafael Moni Feb 03 '17 at 12:42
  • 2
    If #3 is obsolete, what should we do now? – Menasheh Jul 19 '17 at 01:26
  • /etc/rc.local will not work, it will run when you connect to the network, not at startup. – 12431234123412341234123 Oct 24 '17 at 16:25
  • So, will these methods run the commands as root? – NoOne Sep 04 '19 at 19:13
68

You don't need root, or to even login.

You can edit your crontab (crontab -e) and create an entry like this:

@reboot /path/to/script.sh

This way, you can run it as a regular user. @reboot just means it's run when the computer starts up (not necessarily just when it's rebooted).

P.S.: Regarding comments that this does not work properly

Some have said that this doesn't work on Debian-based distros, such as Ubuntu. I have personally successfully used this method on both Ubuntu and Mint. There are a few things to consider, however.

The @reboot jobs will run when the cron daemon starts. I've found that on Debian-based distros, this may occur before the /home partition has been mounted. If the script you're running is in your home folder, it will fail.

Additionally, this isn't limited to Debian-based distros, but if your home folder is encrypted, it may not be decrypted until after you login. There is probably no way around this.

Also, your network interface may not be up yet, and if the command requires Internet access, it may fail.

Finally, again, this is not limited to Debian-based distros, but cron runs under a much more limited environment than your shell runs under. In particular, the PATH variable has much fewer paths. It is possible that the command being run isn't found, if it's in, for example, something like $HOME/.local/bin, which may be in your PATH in your shell session, but not under cron. It's even possible that the command being run depends on some environment variable that's not set in cron.

So, there are a number of reasons why your command will to run under cron, but it's not because @reboot doesn't work on your distro.

Dan Jones
  • 1,069
  • 7
  • 9
  • Inorder for crone jobs to work, doesn't the particular user need to log in? The question states even if the user doesn't log in. In that case, would this method still work? – Denis Jan 10 '17 at 13:08
  • 4
    @Qwertylicious, no the user does not need to log in for cron jobs to run. This method works whether or not he's logged in, because cron runs a system process, and when running the user's cron jobs, it runs the job as that user. As long as the computer is turned on, cron will run, regardless of who is logged in. – Dan Jones Jan 10 '17 at 16:38
  • 4
    This does NOT work in Debian and variants; Ubuntu, Mint. – shrimpwagon Dec 05 '19 at 11:48
  • I tried this method on a Debian based system (Rasbian) and it completely locked me out of SSH access. I had to mount the drive on another system so that I could remove this from cron. Fortunately this got me access to the machine via ssh. Not sure why it affected ssh when other services were still running fine. – Phill Healey Jan 06 '20 at 19:04
  • @PhillHealey I have no idea why that would happen on any system. I've used this method on dozens of different systems, running several different distributions and operating systems. It's worked fine on every system I've used it on.

    In fact, unless you're doing this as root, or something in your script is using sudo, there is no way it could affect system processes.

    – Dan Jones Jan 14 '20 at 21:22
  • @shrimpwagon This does work on Ubuntu and Mint. I've used it myself under both. I've added some more information to my reply to explain why it may seem not to work. – Dan Jones Jul 01 '20 at 14:38
  • @DanJones Good update. That makes sense and is probably what is going on. Thank you. – shrimpwagon Jul 02 '20 at 16:05
  • I had the same issue others are having, cron task did not run on boot in Ubuntu. To fix this, I had to run crontab -e inside sudo -i – FutureJJ Mar 10 '22 at 05:31
16

from terminal

  1. create file newshell.sh.desktop in ~/.config/autostart folder:

    gedit ~/.config/autostart/newshell.sh.desktop
    
  2. change Exec, Name and Comment value and add to file: first line

     [Desktop Entry]
     Type=Application
     Exec=/full/link/to/your/newshell.sh
     Name=newshell
     Comment=whatever you want
    
  3. save

or

you can do it from GUI:

  1. run "startup applications" tool in Ubuntu 14.04 you just write it in search box.
  2. add same Exec, Name and Comment.
muru
  • 197,895
  • 55
  • 485
  • 740
  • 7
    Please note that the OP explicitly wanted it to start at system startup before anyone logs in. Autostarted scripts are run only at login. – Gunnar Hjalmarsson Feb 07 '17 at 03:08
3

In your home, you have a file named .bashrc. This file is executed at the opening of your session.

Just put something like this at the end of the file:

sh /path/to/your/script.sh

EDIT: sorry, i didn't answer your question because my solution is executed when a user is logged in...

To execute something before the login, you can try rcconf or rc-file: http://www.debianadmin.com/manage-linux-init-or-startup-scripts.html

anna328p
  • 113
Gp2mv3
  • 1,966
1

Simply edit rc.local nano /etc/init.d/rc.local as follows:

/path/to/my/script.sh || exit 1 
exit 0
Arcsector
  • 121