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



