Howto: print SysV and Upstart services configuration

Write tutorials and howtos in here
There are more tutorials here http://community.linuxmint.com/tutorial/welcome
Forum rules
Do not start a support topic here please. Before you post please read this

Howto: print SysV and Upstart services configuration

Postby xenopeek on Tue Aug 23, 2011 2:02 pm

Intended audience:
This howto is intended for users of Linux Mint based on Ubuntu, who want to see which services are configured on their machine (perhaps to check configuration, or to look for services to disable). This may also be of use to those wanting to see Bash associative arrays or indirect variable references in practice. I'd be happy to give more details on that in the Bash section on this forum.

Description:
The problem I had was that on Linux Mint based on Ubuntu services can be configured either through SysV or through Upstart, and that there isn't an easy way to see the services configured through SysV. Upstart is intended to replace SysV, but still a lot of services are configured through SysV. To complicate matters, because Upstart is currently installed to be compatible with SysV, also on the filesystem it is not easy to see as /etc/init.d contains both SysV and Upstart files.

Script for SysV:
For SysV there are a lot of ways to see the configuration of when services will be started and when they will be stopped, but all also show the Upstart services (because Upstart is installed to be compatible with SysV), without distinction. I've tried bum, rcconf, sysv-rc-conf and chkconfig, and all have this issue. I want clarity :D So I have written a small Bash script that will print the configuration of only the SysV services.

To create it I suggest you create an empty file called lssysv, edit it with gedit (or another plain text editor) and paste the below code into it. Then save & close the file and mark it executable ("chmod +x lssysv"). You can then run the script from the terminal ("./lssysv" from the folder where the file is).
Code: Select all
#!/bin/bash

# if the script was not launched from a terminal, restart it from a terminal
if [[ ! -t 0 ]] && [[ -x /usr/bin/x-terminal-emulator ]]; then
   /usr/bin/x-terminal-emulator -e "bash -c \"$0 $*; read -s -p 'Press enter to continue...'\""
   exit
fi

# only use newlines for splitting strings into arrays
IFS=$'\n'

# get list of all SysV init scripts, and the length of the longest filename
maxlen=0
services=($(find /etc/init.d -type f -executable | sed 's/^.*\///' | sort))
for service in "${services[@]}"; do
   if [[ $maxlen -lt ${#service} ]]; then
      maxlen=${#service}
   fi
done

# get array of configured SysV init scripts per runlevel
for runlevel in 0 1 2 3 4 5 6 S; do
   arrayname="rc$runlevel"
   eval "declare -A $arrayname"
   scripts=($(find /etc/rc${runlevel}.d -type l -executable -name '[SK][0-9][0-9]*' -printf '%f\n'))
   for script in "${scripts[@]}"; do
      action=${script:0:3}
      service=${script:3}
      eval "$arrayname[\$service]=\$action"
   done
done

# print the table
printf "%-${maxlen}.${maxlen}s   0     1     2     3     4     5     6     S  \n" 'service'
printf "%s------------------------------------------------\n" $(yes - | head -n $maxlen | tr -d '\n')
for service in "${services[@]}"; do
   printf "%-${maxlen}s" $service
   for runlevel in 0 1 2 3 4 5 6 S; do
      arrayname="rc$runlevel"
      eval "value=\${$arrayname[\$service]}"
      printf " [%3.3s]" $value
   done
   printf "\n"
done

Example output:
As an example, below are the first few lines of the SysV configuration on my machine:
Code: Select all
service                   0     1     2     3     4     5     6     S 
-----------------------------------------------------------------------
acpi-support            [   ] [K20] [S99] [S99] [S99] [S99] [   ] [   ]
binfmt-support          [   ] [   ] [S90] [S90] [S90] [S90] [   ] [   ]
bluetooth               [K74] [K74] [S25] [S25] [S25] [S25] [K74] [   ]
bootlogd                [   ] [   ] [   ] [   ] [   ] [   ] [   ] [   ]
brltty                  [   ] [   ] [   ] [   ] [   ] [   ] [   ] [S25]
cryptdisks              [S48] [   ] [   ] [   ] [   ] [   ] [S48] [   ]
cryptdisks-early        [S59] [   ] [   ] [   ] [   ] [   ] [S59] [   ]

As a quick reminder: SysV configuration is based on "runlevels", where a service can either be started on a specific runlevel, or stopped on a specific runlevel. For Linux Mint based on Ubuntu the default runlevel is 2, which is full multi-user mode. Runlevels 3, 4 and 5 are identical to runlevel 2. Runlevel 0 is for system halt, 1 is for single-user rescue mode, 6 is for system reboot and S is for switching between runlevels.

The configuration for each runlevel is shown in a separate column. A "K" in the value means the service is killed at that runlevel, a "S" in the value means the service is started at that runlevel. The number after the "K" or "S" indicates the order in which the services for that runlevel are killed or started.

Script for Upstart:
For Upstart there is an easy way to show the configuration of when services will be started and when they will be stopped:
Code: Select all
initctl show-config

Although this works, it outputs the configuration unsorted. So it can be rather cumbersome to use if you are looking for a specific service in the list. This Bash script is an alternative, showing a sorted list of when the each service is started.

To create it I suggest you create an empty file called lsupstart, edit it with gedit (or another plain text editor) and paste the below code into it. Then save & close the file and mark it executable ("chmod +x lsupstart"). You can then run the script from the terminal ("./lsupstart" from the folder where the file is).

Code: Select all
#!/bin/bash

# if the script was not launched from a terminal, restart it from a terminal
if [[ ! -t 0 ]] && [[ -x /usr/bin/x-terminal-emulator ]]; then
   /usr/bin/x-terminal-emulator -e "bash -c \"$0 $*; read -s -p 'Press enter to continue...'\""
   exit
fi

# only use newlines for splitting strings into arrays
IFS=$'\n'

# get list of Upstart services and "start on" configuration, and the length of the longest service name
maxlen=0
list=($(initctl show-config | egrep '^[^ ]|^  start on ' | sed -e :a -e '$!N;s/\n  /\t/;ta' -e 'P;D' | sort))
for item in "${list[@]}"; do
   service=${item%%$'\t'*}
   if [[ $maxlen -lt ${#service} ]]; then
      maxlen=${#service}
   fi
done

# print the table
maxsolen=$(($(tput cols) - $maxlen - 1))
printf "%-${maxlen}.${maxlen}s start on\n" 'service'
printf "%s\n" $(yes - | head -n $(tput cols) | tr -d '\n')
for item in "${list[@]}"; do
   service=${item%%$'\t'*}
   starton=${item##*start on }
   if [[ $service = $starton ]]; then
      printf "%-${maxlen}s\n" $service
   else
      printf "%-${maxlen}s %-.${maxsolen}s\n" $service $starton
      starton=${starton:$maxsolen}
      while [[ ${#starton} -gt 0 ]]; do
         printf "%-${maxlen}.${maxlen}s %-.${maxsolen}s\n" '' $starton
         starton=${starton:$maxsolen}
      done   
   fi
done
Last edited by xenopeek on Sun Jan 29, 2012 3:49 pm, edited 1 time in total.
Reason: Updated the script
Image
Linux Mint 14 Nadia / 64-bit / Cinnamon
User avatar
xenopeek
Level 20
Level 20
 
Posts: 10515
Joined: Wed Jul 06, 2011 3:58 am
Location: The Netherlands

Linux Mint is funded by ads and donations.
 

Return to Tutorials / Howtos

Who is online

Users browsing this forum: chatan and 12 guests