I usually just copy some existing script like /etc/init.d/ssh, remove extra things and edit remaining things. This is not very convenient.

Is there a simple tool to create good Debian initscripts?

Expecting something like this:

r@l:~# generate_initscript ololo \
    --start-command='daemon --name ololo /usr/bin/ololo' \
    --stop-command='daemon --name ololo --stop' > /etc/init.d/ololo
r@l:~# cat /etc/init.d/ololo
#! /bin/sh

### BEGIN INIT INFO
# Provides:     ololo
# Required-Start:   $remote_fs $syslog
# Required-Stop:    $remote_fs $syslog
# Default-Start:    2 3 4 5
# Default-Stop:     
# Short-Description:    'ololo' script created by generate_initscript
### END INIT INFO

set -e

. /lib/lsb/init-functions

case "$1" in
  start)
    daemon --name ololo /usr/bin/ololo
    ;;
  stop)
    daemon --name ololo --stop
    ;;
  *)
    echo "Usage: /etc/init.d/ololo {start|stop}"
    exit 1
esac

exit 0
share|improve this question
1  
Maybe MetaInit is worth mentioning too: wiki.debian.org/MetaInit or packages.debian.org/jessie/metainit – mivk Jun 12 '15 at 17:09

Debian and its derivatives have a file called skeleton, located in the directory /etc/init.d, which is supposed to do precisely that, i.e. help out users write adequate scripts. I have used it several times, it seems to me to be exactly what you are searching for.

share|improve this answer
    
How to create the initscript based on skeleton without using the text editor? For example, using some tool that makes editing based on your command line options? – Vi. Dec 27 '13 at 21:06
    
Bonus points if such tool also be portable across various init systems. – Vi. Dec 27 '13 at 21:06
5  
Scripting without a text editor would be a hell of a trick. Perchance have you noticed that your name is "VI"? Come on. – Fopedush Dec 27 '13 at 22:45
up vote 0 down vote accepted

I have found this gist: https://gist.github.com/naholyr/4275302

This is basically what was I was searching for.

Here is my (modified) version of the script:

#!/bin/bash

SERVICE_FILE=$(tempfile)

cat >> $SERVICE_FILE <<\EOF
#!/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 "$PIDFILE" ] && kill -0 $(cat "$PIDFILE"); 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
    ;;
  restart)
    stop
    start
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|uninstall}"
esac
EOF

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 "1b. chmod +x"
  chmod 755 "/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 ---"
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.