The officially official Devuan Forum!

You are not logged in.

#1 2024-09-22 13:42:58

dindusmith
Member
Registered: 2024-09-22
Posts: 6  

Journey to create a startup service script

I am a novice of sysvinit, but I like its simplicity. However, I don’t understand the script creation syntax of sysvinit, so I started searching github. Finally, I found a tool that can semi-automatically create service scripts. I copied it and performed the following operations:

1. I created a /etc/inittools directory, which contained the tool create, a template file, and a Readme file for creating service scripts

The content of create is as follows:

#!/bin/bash

SERVICE_FILE=$(tempfile)

if [ ! -e service.sh ]; then
  echo "--- Download template ---"
  echo "I'll now download the service.sh, because is is not downloaded."
  echo "..."
  wget -q https://raw.githubusercontent.com/wyhasany/sample-service-script/master/service.sh
  if [ "$?" != 0 ]; then
    echo "I could not download the template!"
    echo "You should now download the service.sh file manualy. Run therefore:"
    echo "wget https://raw.githubusercontent.com/wyhasany/sample-service-script/master/service.sh"
    exit 1
  else
    echo "I donloaded the tmplate sucessfully"
    echo ""
  fi
fi

echo "--- Copy template ---"
cp service.sh "$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=""
  if [ "$3" = "" ]; then
    while [ "$VAL" = "" ]; do
      echo -n "${2:-$1} : "
      read VAL
      if [ "$VAL" = "" ]; then
        echo "Please provide a value"
      fi
    done
  else
    VAL=${@:3:($#-2)}
  fi
  VAL=$(printf '%s' "$VAL")
  eval $1=$VAL
  local rstr=$(printf '%q' "$VAL")
  rstr=$(echo $rstr | sed -e 's/[\/&]/\\&/g') # escape search string for sed http://stackoverflow.com/questions/407523/escape-a-string-for-a-sed-replace-pattern
  sed -i "s/<$1>/$rstr/g" $SERVICE_FILE
}

prompt_token 'NAME'        'Service name' $1
if [ -f "/etc/init.d/$NAME" ]; then
  echo "Error: service '$NAME' already exists"
  exit 1
fi

prompt_token 'DESCRIPTION' ' Description' $2
prompt_token 'COMMAND'     '     Command' $3
prompt_token 'USERNAME'    '        User' $4
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 didn't give 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 ---"

The content of template is as follows:

#!/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 ] && [ -s $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"
 # Try with this command line instead of above if not workable
 # su -s /bin/sh $RUNAS -c "$CMD" > "$PIDFILE"
 
  sleep 2
  PID=$(cat $PIDFILE)
    if pgrep -u $RUNAS -f $NAME > /dev/null
    then
      echo "$NAME is now running, the PID is $PID"
    else
      echo ''
      echo "Error! Could not start $NAME!"
    fi
}

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 was not removed: $LOGFILE" >&2
    update-rc.d -f $NAME remove
    rm -fv "$0"
  else
    echo "Abort!"
  fi
}

status() {
    printf "%-50s" "Checking <NAME>..."
    if [ -f $PIDFILE ] && [ -s $PIDFILE ]; then
        PID=$(cat $PIDFILE)
            if [ -z "$(ps axf | grep ${PID} | grep -v grep)" ]; then
                printf "%s\n" "The process appears to be dead but pidfile still exists"
            else    
                echo "Running, the PID is $PID"
            fi
    else
        printf "%s\n" "Service not running"
    fi
}

case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  status)
    status
    ;;
  uninstall)
    uninstall
    ;;
  restart)
    stop
    start
    ;;
  *)
    echo "Usage: $0 {start|stop|status|restart|uninstall}"
esac

The content of ReadMe is as follows:

**This tool directory is used to use the create tool in the directory to generate the service script in /etc/init.d/**

2. Then give it executable permissions, sudo chmod +x /etc/inittools/create
3. In this way, every time I need to create a service, I enter /etc/inittools and execute create. It is semi-automatic. Hope it helps you,Cheers

Offline

#2 2024-09-23 11:05:42

stopAI
Member
Registered: 2023-04-04
Posts: 186  

Re: Journey to create a startup service script

Thank you for sharing this.

Offline

#3 2024-09-23 14:29:51

s1mple
Member
Registered: 2023-11-13
Posts: 8  

Re: Journey to create a startup service script

Never mind me. I just thought I'd leave a reference to the LSB standard on init scripts for future hackers.

Linux Standard Base Core Specification 4.1 - VIII. System Initialization

Offline

Board footer