Depending on what sort of scripts you need to run.. For services and the like you should use upstart. But for a user script these should be launched as session scripts by gnome! Have a look under System > Preferences > Startup Applications.
On a side note if you need some scripts to be run on terminal login you can add them to the .bash_login file in your home directory.
For 14.04 and older
A simple command (one which doesn't need to remain running) could use an Upstart job like:
start on startup
task
exec /path/to/command
Save this in a .conf file in /etc/init (if you need it to run as root when the system boots up), or in ~/.config/upstart (if you need it
to run as your user when you log in).
To execute commands as a specific user, use sudo -i -u (-i to also run the login shell). For example, to establish a persistent SSH tunnel, where myhost is definde in johndoes ~/.ssh/config file:
Note that if /etc/rc.local did not exist (as is the case on Ubuntu since 16.04), you need to add a shebang line at the top (e.g. #!/bin/bash), and ensure the file is executable:
To run a (short-lived)1 command at startup using systemd, you can use a systemd unit of type OneShot. For example, create /etc/systemd/system/foo.service containing:
[Unit]
Description=Job that runs your user script
[Service]
ExecStart=/some/command
Type=oneshot
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
You can run multiple commands from the same service file, using multiple ExecStart lines:
[Service]
ExecStart=/some/command
ExecStart=/another/command some args
ExecStart=-/a/third/command ignore failure
The command must always be given with the full path. If any command fails, the rest aren't run. A - before the path tells systemd to ignore a non-zero exit status (instead of considering it a failure).
For user sessions, you can create the systemd unit in ~/.config/systemd/user instead. This should work with 16.04 onwards, but not earlier releases of Ubuntu with systemd (since those still used Upstart for user sessions). User session units can be controlled with the same commands as with system services, but with the --user option added:
systemctl --user daemon-reload
systemctl --user status foo.service
Shell syntax
Note that, unlike Upstart, systemd doesn't run the Exec* commands through a shell. It performs some limited variable expansion and multiple command (separated by ;) itself, but that's about it as far as shell-like syntax goes. For anything more complicated, say redirection or pipes, wrap your command in sh -c '...' or bash -c '...'.
There are different ways to automatically run commands:
The upstart system will execute all scripts from which it finds a configuration in directory /etc/init. These scripts will run during system startup (or in response to certain events, e.g., a shutdown request) and so are the place to run commands that do not interact with the user; all servers are started using this mechanism.
A shell script named .gnomerc in your home directory is automatically sourced each time you log in to a GNOME session. You can put arbitrary commands in there; environment variables that you set in this script will be seen by any program that you run in your session.
Note that the session does not start until the .gnomerc script is finished; therefore, if you want to autostart some long-running program, you need to append & to the program invocation, in order to detach it from the running shell.
The menu option System -> Preferences -> Startup Applications allows you to define what applications should be started when your graphical session starts (Ubuntu predefines quite some), and add or remove them to your taste. This has almost the same purpose and scope of the .gnomerc script, except you don't need to know sh syntax (but neither can you use any sh programming construct).
$HOME/.config/autostart contains the startup application list. .desktop files in this folder will be executed on startup. It may need executable permission (chmod +x startup.desktop).
Here "</path/to/script>" is replaced with path to your script.sh
If you place your script myscript in /usr/local/bin so that it can be executed directly by command, you can write myscript instead of "</path/to/script>".
Sample example of myscript.sh:
#!/bin/bash
<commands to be executed>
exit
Result:
.desktop file will be launched from $HOME/.config/autostart which execute script by Exec=
This answer still uses cron but uses a different method than the top voted answer. This works since Ubuntu 16.04 but probably supported much sooner. It's just that I started using cron to run jobs when computer boots up since 16.04.
When does cron run?
In comments someone asked "when do they run?". You can tell in syslog / journalctl:
$ journalctl -b | grep cron
Jan 02 16:54:40 alien cron[919]: (CRON) INFO (pidfile fd = 3)
Jan 02 16:54:40 alien cron[919]: (CRON) INFO (Running @reboot jobs)
Jan 02 16:54:40 alien systemd[1]: Started Run anacron jobs.
Jan 02 16:54:40 alien anacron[949]: Anacron 2.3 started on 2018-01-02
Jan 02 16:54:40 alien anacron[949]: Normal exit (0 jobs run)
Jan 02 16:54:40 alien CRON[952]: pam_unix(cron:session): session opened for user root by (uid=0)
Jan 02 16:54:40 alien CRON[954]: pam_unix(cron:session): session opened for user root by (uid=0)
Jan 02 16:54:40 alien CRON[951]: pam_unix(cron:session): session opened for user root by (uid=0)
Jan 02 16:54:40 alien CRON[950]: pam_unix(cron:session): session opened for user root by (uid=0)
Jan 02 16:54:40 alien CRON[985]: (root) CMD ( /usr/local/bin/cron-reboot-cycle-grub-background)
Jan 02 16:54:40 alien CRON[954]: pam_unix(cron:session): session closed for user root
Jan 02 16:54:40 alien cron[919]: sendmail: Cannot open smtp.gmail.com:587
Jan 02 16:54:40 alien CRON[952]: pam_unix(cron:session): session closed for user root
Jan 02 16:54:40 alien cron[919]: sendmail: Cannot open smtp.gmail.com:587
Jan 02 16:54:40 alien CRON[950]: pam_unix(cron:session): session closed for user root
One thing to note is cron can email you status of jobs run and @reboot jobs run so early network manager and email won't be running unless you put a sleep command into your script(s).
Where to put your scripts
Put your scripts in the directory /etc/cron.d:
$ ll /etc/cron.d
total 44
drwxr-xr-x 2 root root 4096 Nov 26 19:53 ./
drwxr-xr-x 139 root root 12288 Dec 31 13:58 ../
-rw-r--r-- 1 root root 244 Dec 28 2014 anacron
-rw-r--r-- 1 root root 148 Feb 18 2017 cycle-grub-background
-rw-r--r-- 1 root root 138 Mar 5 2017 display-auto-brightness
-rw-r--r-- 1 root root 460 Nov 26 19:53 nvidia-hdmi-sound
-rw-r--r-- 1 root root 102 Feb 9 2013 .placeholder
-rw-r--r-- 1 root root 224 Nov 19 2016 touch-vmlinuz
-rw-r--r-- 1 root root 700 Aug 5 11:15 turn-off-hyper-threading
What does a script look like?
Here are a couple of scripts I have setup to run each boot:
You should use upstart for this. Upstart is used for Ubuntu processes that are automatically started. It is an enhanced solution like the old System-V init.d scripts. It also allows you to put in prerequisites to the start of your script (i.e. do you need the network running? etc.)
If you want your script to run before systemd right after kernel starts, AFAIK the way is adding init=/path/to/script to the kernel command line in /boot/grub/grub.cfg or more future proof make your own menu entry in /etc/grub.d/40_custom by copying a menu entry from /boot/grub/grub.cfg and making needed changes (and running update-grub after that for grub to add your custom file to /boot/grub/grub.cfg).
linux /boot/vmlinuz-5.4.0-26-generic ... ro quiet splash
change to
linux /boot/vmlinuz-5.4.0-26-generic ... ro quiet splash init=/path/to/script
Take care to properly put e.g. #!/bin/bash on the first line and exec /sbin/init (if /sbin/init exists on your system - on mine it points to systemd) at the end to avoid kernel panic.
One approach is to add an @reboot cron task:
crontab -e
will allow you to edit your cron.Adding a line like this to it:
will execute that script once your computer boots up.
Depending on what sort of scripts you need to run.. For services and the like you should use upstart. But for a user script these should be launched as session scripts by gnome! Have a look under System > Preferences > Startup Applications.
On a side note if you need some scripts to be run on terminal login you can add them to the .bash_login file in your home directory.
For 14.04 and older
A simple command (one which doesn't need to remain running) could use an Upstart job like:
Save this in a
.conf
file in/etc/init
(if you need it to run as root when the system boots up), or in~/.config/upstart
(if you need it to run as your user when you log in).You can add commands to
/etc/rc.local
:This executes the commands as root.
To execute commands as a specific user, use
sudo -i -u
(-i
to also run the login shell). For example, to establish a persistent SSH tunnel, wheremyhost
is definde injohndoe
s~/.ssh/config
file:Note that if
/etc/rc.local
did not exist (as is the case on Ubuntu since 16.04), you need to add a shebang line at the top (e.g.#!/bin/bash
), and ensure the file is executable:For 15.04 and later:
To run a (short-lived)1 command at startup using
systemd
, you can use a systemd unit of typeOneShot
. For example, create/etc/systemd/system/foo.service
containing:Then run:
Essentially, this is just converting a typical Upstart job to a systemd one (see Systemd for Upstart users).
You can run multiple commands from the same service file, using multiple
ExecStart
lines:The command must always be given with the full path. If any command fails, the rest aren't run. A
-
before the path tells systemd to ignore a non-zero exit status (instead of considering it a failure).Relevant:
man 5 systemd.service
For user sessions, you can create the systemd unit in
~/.config/systemd/user
instead. This should work with 16.04 onwards, but not earlier releases of Ubuntu with systemd (since those still used Upstart for user sessions). User session units can be controlled with the same commands as with system services, but with the--user
option added:Shell syntax
Note that, unlike Upstart, systemd doesn't run the
Exec*
commands through a shell. It performs some limited variable expansion and multiple command (separated by;
) itself, but that's about it as far as shell-like syntax goes. For anything more complicated, say redirection or pipes, wrap your command insh -c '...'
orbash -c '...'
.1As opposed to long-lived daemons.
There are different ways to automatically run commands:
The upstart system will execute all scripts from which it finds a configuration in directory
/etc/init
. These scripts will run during system startup (or in response to certain events, e.g., a shutdown request) and so are the place to run commands that do not interact with the user; all servers are started using this mechanism.You can find a readable introduction to at: http://upstart.ubuntu.com/getting-started.html the man pages
man 5 init
andman 8 init
give you the full details.A shell script named
.gnomerc
in your home directory is automatically sourced each time you log in to a GNOME session. You can put arbitrary commands in there; environment variables that you set in this script will be seen by any program that you run in your session.Note that the session does not start until the
.gnomerc
script is finished; therefore, if you want to autostart some long-running program, you need to append&
to the program invocation, in order to detach it from the running shell.The menu option System -> Preferences -> Startup Applications allows you to define what applications should be started when your graphical session starts (Ubuntu predefines quite some), and add or remove them to your taste. This has almost the same purpose and scope of the
.gnomerc
script, except you don't need to knowsh
syntax (but neither can you use anysh
programming construct).$HOME/.config/autostart
contains the startup application list..desktop
files in this folder will be executed on startup. It may need executable permission (chmod +x startup.desktop
).Sample example for
.desktop
file:Here
"</path/to/script>"
is replaced with path to yourscript.sh
If you place your scriptmyscript
in/usr/local/bin
so that it can be executed directly by command, you can writemyscript
instead of"</path/to/script>"
.Sample example of
myscript.sh
:Result:
.desktop
file will be launched from$HOME/.config/autostart
which execute script byExec=
For simple things you can add a command in System->Preferences->Sessions pointing to the location of your script.
Alternatively you can add it to /etc/init.d/rc.local or make an upstart job if it's a more low level stuff.
Take a look at https://help.ubuntu.com/community/UbuntuBootupHowto for more info
cron
answer implemented different from top votedThis answer still uses
cron
but uses a different method than the top voted answer. This works since Ubuntu 16.04 but probably supported much sooner. It's just that I started usingcron
to run jobs when computer boots up since 16.04.When does
cron
run?In comments someone asked "when do they run?". You can tell in syslog / journalctl:
One thing to note is
cron
can email you status of jobs run and@reboot
jobs run so early network manager and email won't be running unless you put asleep
command into your script(s).Where to put your scripts
Put your scripts in the directory
/etc/cron.d
:What does a script look like?
Here are a couple of scripts I have setup to run each boot:
You should use upstart for this. Upstart is used for Ubuntu processes that are automatically started. It is an enhanced solution like the old System-V init.d scripts. It also allows you to put in prerequisites to the start of your script (i.e. do you need the network running? etc.)
If you want your script to run before systemd right after kernel starts, AFAIK the way is adding
init=/path/to/script
to the kernel command line in/boot/grub/grub.cfg
or more future proof make your own menu entry in/etc/grub.d/40_custom
by copying a menu entry from/boot/grub/grub.cfg
and making needed changes (and runningupdate-grub
after that forgrub
to add your custom file to/boot/grub/grub.cfg
).change to
Take care to properly put e.g.
#!/bin/bash
on the first line andexec /sbin/init
(if/sbin/init
exists on your system - on mine it points to systemd) at the end to avoid kernel panic.