Making scripts run at boot time with Debian
Posted by Steve on Mon 11 Oct 2004 at 13:01
Debian uses a Sys-V like init system for executing commands when the system runlevel changes - for example at bootup and shutdown time.
If you wish to add a new service to start when the machine boots you should add the necessary script to the directory /etc/init.d/. Many of the scripts already present in that directory will give you an example of the kind of things that you can do.
Here's a very simple script which is divided into two parts, code which always runs, and code which runs when called with "start" or "stop".
#! /bin/sh
# /etc/init.d/blah
#
# Some things that run always
touch /var/lock/blah
# Carry out specific functions when asked to by the system
case "$1" in
start)
echo "Starting script blah "
echo "Could do more here"
;;
stop)
echo "Stopping script blah"
echo "Could do more here"
;;
*)
echo "Usage: /etc/init.d/blah {start|stop}"
exit 1
;;
esac
exit 0
Once you've saved your file into the correct location make sure that it's executable by running "chmod 755 /etc/init.d/blah".
Then you need to add the appropriate symbolic links to cause the script to be executed when the system goes down, or comes up.
The simplest way of doing this is to use the Debian-specific command update-rc.d:
root@skx:~# update-rc.d blah defaults Adding system startup for /etc/init.d/blah ... /etc/rc0.d/K20blah -> ../init.d/blah /etc/rc1.d/K20blah -> ../init.d/blah /etc/rc6.d/K20blah -> ../init.d/blah /etc/rc2.d/S20blah -> ../init.d/blah /etc/rc3.d/S20blah -> ../init.d/blah /etc/rc4.d/S20blah -> ../init.d/blah /etc/rc5.d/S20blah -> ../init.d/blah
If you wish to remove the script from the startup sequence in the future run:
root@skx:/etc/rc2.d# update-rc.d -f blah remove update-rc.d: /etc/init.d/blah exists during rc.d purge (continuing) Removing any system startup links for /etc/init.d/blah ... /etc/rc0.d/K20blah /etc/rc1.d/K20blah /etc/rc2.d/S20blah /etc/rc3.d/S20blah /etc/rc4.d/S20blah /etc/rc5.d/S20blah /etc/rc6.d/K20blah
This will leave the script itself in place, just remove the links which cause it to be executed.
You can find more details of this command by running "man update-rc.d".
I could not agree more. I have no idea how exactly are those run-levels interpreted by the system.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
i am working on solaris 10 x86 .so could u help me in this.
[ Parent | Reply to this comment ]
Too bad many other linux-solutions and independent projects in general suffer from the same syndrome... ;/
[ Parent | Reply to this comment ]
Also, I switch between a dual and single display config for X. How would I do that in your scheme?
Thanks.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ View Steve's Scratchpad | View Weblogs ]
It is best to use su as you suggested.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
Typical Linux, multiple ways to obtain the same result. I admit Debian is a bit less than intuitive at times but that is how they keep the riff raff out. ;=>
Cheers.
T
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
If you don't like the old Debian init scripts you could try installing initng, also should improve boot times quite a lot although its mostly used by Gentooers but there seems to be Debian builds (At least some old ones in experimental).
http://www.initng.org/ - Seems down currently
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
specifically look at @reboot
that is easy and will "make scripts run at boot time" only.
[ Parent | Reply to this comment ]
and if Gentoo is so GREATE, then why are you even here!?
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
Help me please!!!
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
#! /bin/sh
# /etc/init.d/blah
#
# Some things that run always
touch /var/lock/blah
# Carry out specific functions when asked to by the system
case ââ¬Å$1â&aci rc;¬Â³ in
start)
HOST=ââ¬â¢10.147.25 1.90ââ¬Â²
USER=ââ¬â¢tritech&A tilde;¢â¬â¢
PASSWD=ââ¬â¢tritech ââ¬â¢
ftp -n $HOST <<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
get candle1.C
END_SCRIPT
;;
stop)
echo ââ¬ÅStarting script blah ââ¬ï¿½
;;
*)
exit 1
;;
esac
exit 0
this is my script in which i am trying to copy the file candle1.C from an ftp server at the time of starting the system so i had put this file in /etc/init.d/blah .but it is not working , instead of these ftp commands if am using mkdir d something like command it is working means this script is working but for using an ftp what i have to do , or it is possible to start an ftp connection at the time of init process.plz help me.
[ Parent | Reply to this comment ]
Sysvinit is the best way known to manage all the complexity involved in making any combination of the 10,000+ Debian packages load the various daemons they need, in the order they need, only to the extent they are installed, and have them all work smoothly together. The older BSD init system was simpler, but less capable-- the init scripts had to be edited for every package you added that needed to start at boot time, and the order was always a potential source of a problem. That is why most Linux distributions use sysvinit-- it has proven its value over many years.
Each package that needs to load at a certain runlevel puts one script in /etc/init.d, usually named with the package name. This allows you to start, stop, restart, reload, etc. it by typing "/etc/init.d/mypackage start" (or stop or reload or whatever). If you write a script, use others as a template, and change what you need to change. Test the script by typing these commands manually (probably at a root shell). If the script works properly here, it should work in runlevels. However, to answer the last plea for help, this script does NOT start anything automatically at ANY runlevel. We still need one more thing for that.
To do that, we create symlinks to these scripts in the various runlevel directories. For example, if we normally run at runlevel 2 (as Debian does by default) and we want mypackage to run as start, then create two links in /etc/rc2.d, one named S99mypackage and one named K99mypackage. S means Start, and K means Kill (stop) the process. When the system goes into runlevel 2, all the start links in /etc/rc2.d will be run one after another. The 99 tells the system WHEN it should be run-- they run in numerical order from 01-99 (and in alpha order within those numeric levels, I think). So 99 will be run last, and everything should basically already be up by then, usually a good choice for your personal stuff. But if you want it run before thing1 and after thing2, then pick a more appropriate number. If you want it started first and stopped last, then name the links S01mypackage and K99mypackage. You can also disable the link temporarily by renaming the uppercase S or K to lowercase-- only the uppercase letters will be run.
As to "why so many runlevels, if Debian only uses two?"-- you can use them any way you want. Runlevel S (or 1) is single-user maintenance mode (which may not even mount your disks). Runlevel 2 (in Debian) is multi-user. Some distributions once used runlevel 3 for networking, or 5 for X windows. Now both (networking and X) seem to be nearly universal, and are not usually put on separate runlevels. But if you want to do that, you can. It's your system, do what you want. Maybe you have a system needs to be configured differently at home and work, or when the kids are using it. You can set runlevels for these different modes.
If you want the simpler "just run this at boot time" of BSD, just add your script to the /etc/rc.local script which runs after the rest of the boot process is complete. So you CAN have it both ways.
Hope this clears up some of the confusion. I'd say RTFM, but sometimes the manuals are long on detail and short on 30,000 foot-level explanation of the concepts.
[ Parent | Reply to this comment ]
-- Specifically, around what happens when a particular package is upgraded, but I guess if I'm not packaging my scripts into a .deb file, I really don't need to worry about that. ( I think I got confused when I was trying to do things like disable proftpd for an indeterminate amount of time. ) apt-get update will automatically update proftpd ( and from what I understood, possibly re-activate the sysvinit links. )
Anyway, I like your quick view above so much that I'm going to save it in a file on my servers. I'd credit you, but it was posted anonymously. I'll credit the URL instead. Thanks again.
Regarding the attitude that the point of Linux isn't adoption, I find that short-sighted. Perhaps I'm just an optimist, but I really think that the best thing for all Linux users is more Linux usage. If for no other reason, hardware support. We Linux users don't have a lot of economic influence on hardware manufacturer's -- there's not a lot of incentive to even passively check and see if Linux can work. That's not going to change until the hardware vendors start hurting from lack of sales because they won't support Linux. And that's not going to happen until there are enough people running Linux to care...
[ Parent | Reply to this comment ]
so here the script of /etc/init.d/bluetooth
what to change here?
#! /bin/sh
### BEGIN INIT INFO
# Provides: bluetooth
# Required-Start: $local_fs $syslog $remote_fs dbus
# Required-Stop: $local_fs $syslog $remote_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start bluetoothd
### END INIT INFO
. /lib/lsb/init-functions
set -e
case "$1" in
start)
#currently this init script exists only because of what appears to be
#an egg and chicken problem
# bluetoothd normally starts up by udev rules. it needs dbus to function,
# but dbus doesn't start up until after udev finishes triggering
#
if [ ! -f /sbin/udevadm.upgrade ]; then
udevadm trigger --subsystem-match=bluetooth
fi
;;
stop)
pkill -TERM bluetoothd || true
;;
restart|force-reload)
$0 stop
$0 start
;;
status)
status_of_proc "bluetoothd" "bluetooth" && exit 0 || exit $?
;;
*)
N=/etc/init.d/bluetooth
# echo "Usage: $N {start|stop|restart|reload|force-reload|status}" >&2
echo "Usage: $N {start|stop|restart|force-reload|status}" >&2
exit 1
;;
esac
exit 0
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
Nice guide, I didn't know it was so easy.
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
Augusto Molina
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
I am using an open-source software that I worked on at my company,
but it has an script to run on boot time for redhat, and now that it's
open I am doing it for Debian too.
I wrote a script to run on debian following this tutorial, but the software
needs root access to output the right things ...
the question is: WHAT IF MY PROGRAM NEEDS TO RUN AS ROOT?
[ Parent | Reply to this comment ]
[ View Steve's Scratchpad | View Weblogs ]
Scripts placed in the fashion described here are started as root. No special things need to be done to change that..
[ Parent | Reply to this comment ]
I expected that too, but, looking at the log I got this output
[Fri Jan 6 22:09:12 2012] [debug] LDC running without super-user permission.
So, it isn't running is not root.
Any ideas?
[ Parent | Reply to this comment ]
[ View Steve's Scratchpad | View Weblogs ]
I wonder if that actually refers to something else - CAPABILITIES - rather than "running as root"?
Once you've started the script run "ps -ef" and I'm certain you'll see it launched by root at start time - or if you become root and run "/etc/init.d/blah start". (Obviously if you run it as yourself, in a non-root account, it won't start as root.)
[ Parent | Reply to this comment ]
place it to /etc/init/somename
and then service somename start
description "uWSGI server for some_django_site"
start on runlevel [2345] #comment out it to disable autostart
stop on runlevel [!2345]
respawn
exec /server/env/bin/uwsgi -p 2 --home /server/env/ --socket /server/sock/some_django_site.uwsgi.sock --chmod-socket --module runsite --pythonpath /home/some_django_site --daemonize /server/log/some_django_site.uwsgi.log
# home - is the path to our virtualenv directory
# module - is the file name of our wsgi configuration
# pythonpath is the path to our django application
# socket specifies the UNIX socket file to use.
# --enable-threads
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
Here is what i got:
update-rc.d automount defaults
update-rc.d: using dependency based boot sequencing
insserv: warning: script 'K01automount' missing LSB tags and overrides
insserv: warning: script 'automount' missing LSB tags and overrides
So I found out you got to add LSB tags to the top of the script, and here it is:
### BEGIN INIT INFO
# Provides: automount
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time
# Description: Enable service provided by daemon.
### END INIT INFO
Hopefully you will add this info to the tutorial so that people don't get things messed up. Thank you.
[ Parent | Reply to this comment ]
Helped me totally!
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ View Weblogs ]
I do wish Debian would do away with the System V run level scheme, it's all a bit confusing. As I understand it some of the run levels aren't even used?! Gentoo has done away with it already, using "reboot", "nonetwork" etc. instead, it's a bit more intuitive.. as it happens the rc-update tool is much better too...
[ Parent | Reply to this comment ]