# How to quickly see which services are running at login



## Pierre-Marie Baty (Dec 27, 2022)

Hello all FreeBSD users,

With the intent of saving me time when I check in my FreeBSD server over SSH, I added a one-liner to my .profile that tells me which of the machine's configured services are alive and which ones are dead. It's working well and I thought I'd share.

```
#!/bin/sh
printf "Services:"; service -e|while read _LINE; do _SERVICE="$(basename "${_LINE}")"; _STATUS="$(service "${_SERVICE}" status 2>/dev/null)"; test -z "${_STATUS}" && continue; if echo "${_STATUS}"|grep -q -e " enabled" -e " running as pid" -e " Running"; then printf " \033[1;32m${_SERVICE}\033[0m"; elif echo "${_STATUS}"|grep -q -e " not running"; then printf " \033[1;31m${_SERVICE}\033[0m"; else printf " ${_SERVICE}"; fi; done; echo ""; unset _LINE _SERVICE _STATUS
```

This prints something like this on the terminal :

Services: *ip6addrctl **devd* *newsyslog* *syslogd* *ipfw* *local_unbound* *miltersid* *saslauthd* *powerd* *ntpd* *milter-opendkim* *openvpn* *cron* *vboxheadless* *clamav-clamd* *dovecot* *redis* *prosody* *php-fpm* *nginx* *sshd* *ethercalc* *rspamd* *clamav-freshclam* *ethercalc-quickchart* *sendmail*

The color code is trivial, green: service is alive, red: service is currently not running, natural color: state couldn't be determined.

For clarity and FWIW, that one-liner can be broken down as such:

```
#!/bin/sh

# print the line header
printf "Services:"
# acquire the list of all configured services on this machine
service -e|while read _LINE; do
    # isolate the service name and ask for its status
    _SERVICE="$(basename "${_LINE}")"
    _STATUS="$(service "${_SERVICE}" status 2>/dev/null)"
    # ignore services for which a "service status" reports an empty string or an error (non-queriable services)
    test -z "${_STATUS}" && continue;
    # does this status line explicitly indicate the service is running or enabled ?
    if echo "${_STATUS}"|grep -q -e " enabled" -e " running as pid" -e " Running"; then
        # if so, print it in green
        printf " \033[1;32m${_SERVICE}\033[0m"
    # else does this status line explicitly indicate the service is not running ?
    elif echo "${_STATUS}"|grep -q -e " not running"; then
        # if so, print it in red
        printf " \033[1;31m${_SERVICE}\033[0m"
    # else this service status line doesn't have a recognizable pattern
    else
        # so print it in natural colors
        printf " ${_SERVICE}"
    fi
done
# drop a newline to terminate the enumeration and cleanup the variables we used
echo ""
unset _LINE _SERVICE _STATUS
```

Now here's something interesting (for the FreeBSD maintainers) :

*During my trial and error attempts I noticed something flooding /var/log/messages.* It turned out that simply entering "service -e" in the console would yield these lines to be logged :

```
Dec 27 13:11:38 pmbaty root[40286]: /usr/sbin/service: WARNING: $ is not set properly - see rc.conf(5).
Dec 27 13:11:38 pmbaty root[40400]: /usr/sbin/service: WARNING: $vm_enable is not set properly - see rc.conf(5).
Dec 27 13:11:38 pmbaty root[40432]: /usr/sbin/service: WARNING: $unbound_enable is not set properly - see rc.conf(5).
Dec 27 13:11:38 pmbaty root[40445]: /usr/sbin/service: WARNING: $jitsi_videobridge_enable is not set properly - see rc.conf(5).
Dec 27 13:11:38 pmbaty root[40485]: /usr/sbin/service: WARNING: $jicofo_enable is not set properly - see rc.conf(5).
Dec 27 13:11:39 pmbaty root[40651]: /usr/sbin/service: WARNING: $dbus_enable is not set properly - see rc.conf(5).
Dec 27 13:11:39 pmbaty root[40659]: /usr/sbin/service: WARNING: $svnserve_enable is not set properly - see rc.conf(5).
Dec 27 13:11:39 pmbaty root[40667]: /usr/sbin/service: WARNING: $vsftpd_enable is not set properly - see rc.conf(5).
Dec 27 13:11:39 pmbaty root[40705]: /usr/sbin/service: WARNING: $git_daemon_enable is not set properly - see rc.conf(5).
Dec 27 13:11:39 pmbaty root[40732]: /usr/sbin/service: WARNING: $vboxwebsrv_enable is not set properly - see rc.conf(5).
Dec 27 13:11:39 pmbaty root[40740]: /usr/sbin/service: WARNING: $vboxwatchdog_enable is not set properly - see rc.conf(5).
Dec 27 13:11:39 pmbaty root[40752]: /usr/sbin/service: WARNING: $turnserver_enable is not set properly - see rc.conf(5).
Dec 27 13:11:39 pmbaty root[40760]: /usr/sbin/service: WARNING: $sshguard_enable is not set properly - see rc.conf(5).
Dec 27 13:11:39 pmbaty root[40780]: /usr/sbin/service: WARNING: $signal_cli_enable is not set properly - see rc.conf(5).
Dec 27 13:11:39 pmbaty root[40788]: /usr/sbin/service: WARNING: $sentinel_enable is not set properly - see rc.conf(5).
Dec 27 13:11:39 pmbaty root[40796]: /usr/sbin/service: WARNING: $rsyncd_enable is not set properly - see rc.conf(5).
Dec 27 13:11:39 pmbaty root[40816]: /usr/sbin/service: WARNING: $kpropd_enable is not set properly - see rc.conf(5).
Dec 27 13:11:39 pmbaty root[40851]: /usr/sbin/service: WARNING: $clamav_milter_enable is not set properly - see rc.conf(5).
Dec 27 13:11:39 pmbaty root[40880]: /usr/sbin/service: WARNING: $smartd_enable is not set properly - see rc.conf(5).
```
It looks exactly like this bug: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=208445 which appears to be still present in 13.1-RELEASE-p3.

To prevent it from happening I had to edit the rc subroutines in /etc/rc.subr, in the "checkyesno" function:

```
#
# checkyesno var
#    Test $1 variable, and warn if not set to YES or NO.
#    Return 0 if it's "yes" (et al), nonzero otherwise.
#
checkyesno()
{
    eval _value=\$${1}
    # Pierre-Marie Baty -- 2022-12-27 -- extra filter (see below) when passed var is nil
    test -n "${1}" || return 1
    debug "checkyesno: $1 is set to $_value."
    case $_value in

        #    "yes", "true", "on", or "1"
    [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
        return 0
        ;;

        #    "no", "false", "off", or "0"
        # Pierre-Marie Baty -- 2022-12-27 -- added "" (empty string) to prevent flood in /var/log/messages
        # Pierre-Marie Baty -- see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=208445
    [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0|"")
        return 1
        ;;
    *)
        warn "\$${1} is not set properly - see rc.conf(5)."
        return 1
        ;;
    esac
}
```
Basically that routine drops a warning in the logs when any of the variables it tests has anything but the expected values. One first problem here is that when no such variable is defined, or when this variable has an empty value (which a logical mind would assume such a case equals a "no", "false" or "0" value), that warning is raised. I personally find that cluttering my /etc/rc.conf with many explicit XXX_enabled="NO" variables should not be necessary, and that a variable that's commented out or simply not appearing in that file should be assumed to false.

Another problem that popped up is that it seems that the "checkyesno" function in /etc/rc.subr is called once with an empty variable name as argument, resulting in that line to be sent to the logs: "WARNING: $ is not set properly". Adding a test at the top of the function to make it return 1 when it's the case silenced out the error, although I admit it would have been best to dig further in the /usr/sbin/service internals and find out why checkyesno was called with an empty argument in the first place. I confess I didn't bother.

Anyway, these two patches made my /var/log/messages sober again.

Comments, improvements, suggestions all welcome.
Happy end of year,


----------

