Skip to content

Instantly share code, notes, and snippets.

Created December 13, 2012 09:39
Show Gist options
  • Save naholyr/4275302 to your computer and use it in GitHub Desktop.
Save naholyr/4275302 to your computer and use it in GitHub Desktop.
Sample /etc/init.d script

Sample service script for debianoids

Look at LSB init scripts for more information.


Copy to /etc/init.d:

# replace "$YOUR_SERVICE_NAME" with your service's name (whenever it's not enough obvious)
cp "" "/etc/init.d/$YOUR_SERVICE_NAME"
chmod +x /etc/init.d/$YOUR_SERVICE_NAME

Edit the script and replace following tokens:

  • <DESCRIPTION> = Describe your service here (be concise)
  • Feel free to modify the LSB header, I've made default choices you may not agree with
  • <COMMAND> = Command to start your server (for example /home/myuser/.dropbox-dist/dropboxd)
  • <USER> = Login of the system user the script should be run as (for example myuser)

Start and test your service:

service $YOUR_SERVICE_NAME start
service $YOUR_SERVICE_NAME stop

Install service to be run at boot-time:

update-rc.d $YOUR_SERVICE_NAME defaults



The service can uninstall itself with service $NAME uninstall. Yes, that's very easy, therefore a bit dangerous. But as it's an auto-generated script, you can bring it back very easily. I use it for tests and often install/uninstall, that's why I've put that here.

Don't want it? Remove lines 56-58 of the service's script.


Your service will log its output to /var/log/$NAME.log. Don't forget to setup a logrotate :)

I'm noob and/or lazy

Yep, I'm lazy too. But still, I've written a script to automate this :)

wget '' && bash

In this script I will download into a tempfile, replace some tokens, and then show you commands you should run as superuser.

If you feel confident enough with my script, you can sudo the script directly:

wget '' && sudo bash

Note: the cool hipsterish curl $URL | bash won't work here, I don't really want to check why.


Creating the service:


Looking at service files (logs, pid):


Uninstalling service:


echo "--- Download template ---"
wget -q -O "$SERVICE_FILE" ''
chmod +x "$SERVICE_FILE"
echo ""
echo "--- Customize ---"
echo "I'll now ask you some information to customize script"
echo "Press Ctrl+C anytime to abort."
echo "Empty values are not accepted."
echo ""
prompt_token() {
local VAL=""
while [ "$VAL" = "" ]; do
echo -n "${2:-$1} : "
read VAL
if [ "$VAL" = "" ]; then
echo "Please provide a value"
VAL=$(printf '%q' "$VAL")
eval $1=$VAL
sed -i "s/<$1>/$(printf '%q' "$VAL")/g" $SERVICE_FILE
prompt_token 'NAME' 'Service name'
if [ -f "/etc/init.d/$NAME" ]; then
echo "Error: service '$NAME' already exists"
exit 1
prompt_token 'DESCRIPTION' ' Description'
prompt_token 'COMMAND' ' Command'
prompt_token 'USERNAME' ' User'
if ! id -u "$USERNAME" &> /dev/null; then
echo "Error: user '$USERNAME' not found"
exit 1
echo ""
echo "--- Installation ---"
if [ ! -w /etc/init.d ]; then
echo "You don't gave me enough permissions to install service myself."
echo "That's smart, always be really cautious with third-party shell scripts!"
echo "You should now type those commands as superuser to install and run your service:"
echo ""
echo " mv \"$SERVICE_FILE\" \"/etc/init.d/$NAME\""
echo " touch \"/var/log/$NAME.log\" && chown \"$USERNAME\" \"/var/log/$NAME.log\""
echo " update-rc.d \"$NAME\" defaults"
echo " service \"$NAME\" start"
echo "1. mv \"$SERVICE_FILE\" \"/etc/init.d/$NAME\""
mv -v "$SERVICE_FILE" "/etc/init.d/$NAME"
echo "2. touch \"/var/log/$NAME.log\" && chown \"$USERNAME\" \"/var/log/$NAME.log\""
touch "/var/log/$NAME.log" && chown "$USERNAME" "/var/log/$NAME.log"
echo "3. update-rc.d \"$NAME\" defaults"
update-rc.d "$NAME" defaults
echo "4. service \"$NAME\" start"
service "$NAME" start
echo ""
echo "---Uninstall instructions ---"
echo "The service can uninstall itself:"
echo " service \"$NAME\" uninstall"
echo "It will simply run update-rc.d -f \"$NAME\" remove && rm -f \"/etc/init.d/$NAME\""
echo ""
echo "--- Terminated ---"
# Provides: <NAME>
# Required-Start: $local_fs $network $named $time $syslog
# Required-Stop: $local_fs $network $named $time $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Description: <DESCRIPTION>
start() {
if [ -f /var/run/$PIDNAME ] && kill -0 $(cat /var/run/$PIDNAME); then
echo 'Service already running' >&2
return 1
echo 'Starting service…' >&2
local CMD="$SCRIPT &> \"$LOGFILE\" & echo \$!"
su -c "$CMD" $RUNAS > "$PIDFILE"
echo 'Service started' >&2
stop() {
if [ ! -f "$PIDFILE" ] || ! kill -0 $(cat "$PIDFILE"); then
echo 'Service not running' >&2
return 1
echo 'Stopping service…' >&2
kill -15 $(cat "$PIDFILE") && rm -f "$PIDFILE"
echo 'Service stopped' >&2
uninstall() {
echo -n "Are you really sure you want to uninstall this service? That cannot be undone. [yes|No] "
local SURE
read SURE
if [ "$SURE" = "yes" ]; then
rm -f "$PIDFILE"
echo "Notice: log file is not be removed: '$LOGFILE'" >&2
update-rc.d -f <NAME> remove
rm -fv "$0"
case "$1" in
echo "Usage: $0 {start|stop|restart|uninstall}"
Copy link

the script was not working because of a 404 on the so i forked it and made a proper repo out of it here:

Copy link

mehikmat commented May 6, 2014

I think at line 45 there is little bit grammatical mistake.

log file is not be removed
but think either log file is not removed or log file should not be removed is correct.

Copy link

A better way to do this is to use the MataInit package in debian:

Copy link

t2d commented Nov 10, 2014

the links for wget are broken

Copy link

vi commented Jan 17, 2015

Why is always downloaded instead of a here document inside of

Copy link

vi commented Jan 17, 2015

Maybe better to use sed s!<pattern>!user_input!g instead of s/.../.../g. The command can contain /.

Copy link

vi commented Jan 17, 2015

The script also forgets to set the appropriate mode (chmod 755 /etc/init.d/..) for the service.

Copy link

vanjor commented Feb 28, 2015

LOL.. spelling: retart=>restart

Copy link

integrii commented Mar 3, 2015

This is great, but the links no longer work for github. Pull my fork! I fixed them!

Copy link

License ?

Copy link

s/if [ -f /var/run/$PIDNAME ] && kill -0 $(cat /var/run/$PIDNAME); then/if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE"); then/

Copy link

fengye commented Dec 16, 2015 line 18 should be:

if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE"); then

Otherwise if I start my service multiple times, the script won't complain. And afterward if I stop the service, the system will complain about not finding the pid.

Since there's no pull request of gist, please download the updated shell script here:

Copy link

Copy link

Copy link

Can we run the same service multiple times from different directory. Ex: myservice & myservice1 have to run same application from different directory... it is possible?
I have tried the same but either it executive same or get the error...
Please let me know the code for this...
Thanks in advance...

Copy link

Copy link

ceyes commented Apr 19, 2017 should be
if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE"); then

Copy link

timjen3 commented Apr 29, 2017

I had a couple issues with the "start" function above on Ubuntu 16.04 LTS.

  1. For one it references a made up variable like @fengye mentioned above. His fix works for me:
    if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE"); then

  2. For me output of the script was going into the pid file and not the log file which prevented it from shutting down and also was dumb. Had to do this.
    su -c "$CMD" $RUNAS > "$LOGFILE"

  3. The trickiest issue I ran into was with writing the process id to the file. I think it may be because my script uses xonsh and there's a slight delay starting up. I'm not sure, but I found that I had to use the double ampersand here or the pid written to the file would be wrong.
    local CMD="$SCRIPT &> \"$LOGFILE\" && echo \$! > $PIDFILE"

Here's the whole function for convenience:

`start() {
  if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE"); then
    echo 'Service already running' >&2
    return 1
  echo 'Starting service…' >&2
  local CMD="$SCRIPT &> \"$LOGFILE\" && echo \$! > $PIDFILE"
  su -c "$CMD" $RUNAS > "$LOGFILE"
  echo 'Service started' >&2

Copy link

salodev commented Aug 20, 2017

Congrats for your code!! To you and all involved on comments!
Was very helpful for my project!

Copy link

Globik commented Sep 11, 2017

Your $PIDNAME variable is also undefined???

Copy link

deseven commented Nov 20, 2017

kinda retartet

Copy link

naholyr commented Nov 21, 2017

You meant "retarded" I guess. But this kind of comments usually goes with the awful writing too, no surprise ;)

Well it's been 5 years old now, and I think it's totally obsolete since systemd is the new thing (which has been a year or two now). I understand your disappointment if you did not consider this. For your future explorations, please remember to check the publication date of what you're reading, it may help you not being so disappointed that you need to compulsively add such comment.

Copy link

deseven commented Dec 18, 2017

It was a joke and it was based on a couple of things:

  1. Your typo in line 61, which literally says "retart".
  2. There are also incorrect variables usage (PIDFILE vs PIDNAME).
  3. There is no status functionality.
  4. Many people commented on all those issues, but you decided to do nothing.

All in all - this is a really bad example of SysV Init script. I hope i made myself clear and sorry if this offended you.

Copy link

@deseven you are retarded

Copy link

deseven commented Jan 29, 2018

@nitzanav ¯\_(ツ)_/¯

Copy link

Failed to stop testservice.service: Unit testservice.service not loaded.

can someone suggest what this error for.
I took file and copied into /etc/init.d/testservice
i edited the to testservice in

Copy link

fabm22 commented May 24, 2018

Hey guys, hey guys, did you see there was a typo ?????? retart ok ? hein ? ok ? did you see that ?

Copy link

jserpapinto commented May 28, 2018

@deseven do you have a better script template? please share if you do..

Copy link

deseven commented Jul 4, 2018

@johnyserpa this one looks fine for me.

Copy link

For running smth in the background (like runing a nohup java -jar ... commandyou'll have to add the usual & at the end of the actual command run which is su -c "$CMD" $RUNAS > "$PIDFILE". It is useless and certainly not work to add the & at the end of the SCRIPT variable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment