Instantly share code, notes, and snippets.

Embed
What would you like to do?
Sample /etc/init.d script

Sample service script for debianoids

Look at LSB init scripts for more information.

Usage

Copy to /etc/init.d:

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

Edit the script and replace following tokens:

  • <NAME> = $YOUR_SERVICE_NAME
  • <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

Enjoy

Uninstall

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.

Logs?

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 'https://raw.github.com/gist/4275302/new-service.sh' && bash new-service.sh

In this script I will download service.sh 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 'https://raw.github.com/gist/4275302/new-service.sh' && sudo bash new-service.sh

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

Demo

Creating the service:

service-create

Looking at service files (logs, pid):

service-files

Uninstalling service:

service-uninstall

#!/bin/bash
SERVICE_FILE=$(tempfile)
echo "--- Download template ---"
wget -q -O "$SERVICE_FILE" 'https://raw.github.com/gist/4275302/service.sh'
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"
fi
done
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
fi
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
fi
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"
else
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
fi
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 ---"
#!/bin/sh
### BEGIN INIT INFO
# 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>
### END INIT INFO
SCRIPT=<COMMAND>
RUNAS=<USERNAME>
PIDFILE=/var/run/<NAME>.pid
LOGFILE=/var/log/<NAME>.log
start() {
if [ -f /var/run/$PIDNAME ] && kill -0 $(cat /var/run/$PIDNAME); then
echo 'Service already running' >&2
return 1
fi
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
fi
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
stop
rm -f "$PIDFILE"
echo "Notice: log file is not be removed: '$LOGFILE'" >&2
update-rc.d -f <NAME> remove
rm -fv "$0"
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
uninstall)
uninstall
;;
retart)
stop
start
;;
*)
echo "Usage: $0 {start|stop|restart|uninstall}"
esac
@re5et

This comment has been minimized.

Show comment
Hide comment
@re5et

re5et commented Dec 18, 2013

retart

@jschnurholmes

This comment has been minimized.

Show comment
Hide comment
@jschnurholmes

jschnurholmes Mar 25, 2014

Type in service.sh:61: "retart" instead of "restart"

jschnurholmes commented Mar 25, 2014

Type in service.sh:61: "retart" instead of "restart"

@jasonblewis

This comment has been minimized.

Show comment
Hide comment
@jasonblewis

jasonblewis Apr 14, 2014

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

https://github.com/jasonblewis/sample-service-script

jasonblewis commented Apr 14, 2014

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

https://github.com/jasonblewis/sample-service-script

@mehikmat

This comment has been minimized.

Show comment
Hide comment
@mehikmat

mehikmat 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.

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.

@jasonblewis

This comment has been minimized.

Show comment
Hide comment
@jasonblewis

jasonblewis May 23, 2014

A better way to do this is to use the MataInit package in debian: https://wiki.debian.org/MetaInit

jasonblewis commented May 23, 2014

A better way to do this is to use the MataInit package in debian: https://wiki.debian.org/MetaInit

@t2d

This comment has been minimized.

Show comment
Hide comment
@t2d

t2d Nov 10, 2014

the links for wget are broken

t2d commented Nov 10, 2014

the links for wget are broken

@vi

This comment has been minimized.

Show comment
Hide comment
@vi

vi Jan 17, 2015

Why service.sh is always downloaded instead of a here document inside of new-service.sh?

vi commented Jan 17, 2015

Why service.sh is always downloaded instead of a here document inside of new-service.sh?

@vi

This comment has been minimized.

Show comment
Hide comment
@vi

vi Jan 17, 2015

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

vi commented Jan 17, 2015

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

@vi

This comment has been minimized.

Show comment
Hide comment
@vi

vi Jan 17, 2015

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

vi commented Jan 17, 2015

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

@vanjor

This comment has been minimized.

Show comment
Hide comment
@vanjor

vanjor Feb 28, 2015

LOL.. spelling: retart=>restart

vanjor commented Feb 28, 2015

LOL.. spelling: retart=>restart

@integrii

This comment has been minimized.

Show comment
Hide comment
@integrii

integrii Mar 3, 2015

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

integrii commented Mar 3, 2015

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

@YaseenTwati

This comment has been minimized.

Show comment
Hide comment
@YaseenTwati

YaseenTwati commented Jun 3, 2015

License ?

@arhimondr

This comment has been minimized.

Show comment
Hide comment
@arhimondr

arhimondr Aug 24, 2015

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

arhimondr commented Aug 24, 2015

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

@fengye

This comment has been minimized.

Show comment
Hide comment
@fengye

fengye Dec 16, 2015

service.sh 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:
https://gist.githubusercontent.com/fengye/3265b4463e14a569358e/raw/e6b414e10685d283167031538b06cc996f2e5e02/service.sh

fengye commented Dec 16, 2015

service.sh 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:
https://gist.githubusercontent.com/fengye/3265b4463e14a569358e/raw/e6b414e10685d283167031538b06cc996f2e5e02/service.sh

@kiselev-dv

This comment has been minimized.

Show comment
Hide comment
@vladistan

This comment has been minimized.

Show comment
Hide comment
@manohargorantla

This comment has been minimized.

Show comment
Hide comment
@manohargorantla

manohargorantla May 20, 2016

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...

manohargorantla commented May 20, 2016

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...

@x13machine

This comment has been minimized.

Show comment
Hide comment
@x13machine

x13machine commented Jan 2, 2017

@ceyes

This comment has been minimized.

Show comment
Hide comment
@ceyes

ceyes Apr 19, 2017

https://gist.github.com/naholyr/4275302#file-service-sh-L18 should be
if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE"); then

ceyes commented Apr 19, 2017

https://gist.github.com/naholyr/4275302#file-service-sh-L18 should be
if [ -f "$PIDFILE" ] && kill -0 $(cat "$PIDFILE"); then

@timjen3

This comment has been minimized.

Show comment
Hide comment
@timjen3

timjen3 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
  fi
  echo 'Starting service…' >&2
  local CMD="$SCRIPT &> \"$LOGFILE\" && echo \$! > $PIDFILE"
  su -c "$CMD" $RUNAS > "$LOGFILE"
  echo 'Service started' >&2
}

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
  fi
  echo 'Starting service…' >&2
  local CMD="$SCRIPT &> \"$LOGFILE\" && echo \$! > $PIDFILE"
  su -c "$CMD" $RUNAS > "$LOGFILE"
  echo 'Service started' >&2
}
@salojc2006

This comment has been minimized.

Show comment
Hide comment
@salojc2006

salojc2006 Aug 20, 2017

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

salojc2006 commented Aug 20, 2017

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

@Globik

This comment has been minimized.

Show comment
Hide comment
@Globik

Globik Sep 11, 2017

Your $PIDNAME variable is also undefined???

Globik commented Sep 11, 2017

Your $PIDNAME variable is also undefined???

@deseven

This comment has been minimized.

Show comment
Hide comment
@deseven

deseven Nov 20, 2017

kinda retartet

deseven commented Nov 20, 2017

kinda retartet

@naholyr

This comment has been minimized.

Show comment
Hide comment
@naholyr

naholyr 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.

Owner

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.

@deseven

This comment has been minimized.

Show comment
Hide comment
@deseven

deseven 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.

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.

@nitzanav

This comment has been minimized.

Show comment
Hide comment
@nitzanav

nitzanav Dec 22, 2017

@deseven you are retarded

nitzanav commented Dec 22, 2017

@deseven you are retarded

@deseven

This comment has been minimized.

Show comment
Hide comment
@deseven

deseven commented Jan 29, 2018

@nitzanav ¯\_(ツ)_/¯

@satish-cevp

This comment has been minimized.

Show comment
Hide comment
@satish-cevp

satish-cevp Feb 6, 2018

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

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

satish-cevp commented Feb 6, 2018

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

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

@fabm22

This comment has been minimized.

Show comment
Hide comment
@fabm22

fabm22 May 24, 2018

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

fabm22 commented May 24, 2018

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

@johnyserpa

This comment has been minimized.

Show comment
Hide comment
@johnyserpa

johnyserpa May 28, 2018

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

johnyserpa commented May 28, 2018

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

@deseven

This comment has been minimized.

Show comment
Hide comment
@deseven

deseven commented Jul 4, 2018

@johnyserpa this one looks fine for me.

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