When working with Linux init scripts (particularly in Debian-based systems), you might encounter the status_of_proc
function that isn't available in your regular shell environment. This function typically appears in LSB-compliant init scripts but remains undefined elsewhere.
The function is part of the /lib/lsb/init-functions
package in Debian/Ubuntu systems. This library provides various helper functions for init scripts that comply with the Linux Standard Base specification.
# Source the LSB init functions
. /lib/lsb/init-functions
Here's how you can use status_of_proc in your own scripts:
#!/bin/sh
### BEGIN INIT INFO
# Provides: my_service
# Required-Start: $network $local_fs
# Required-Stop: $network $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: My custom service
### END INIT INFO
# Load LSB functions
. /lib/lsb/init-functions
case "$1" in
status)
status_of_proc -p /var/run/my_service.pid "/usr/sbin/my_service" "My Service"
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
For cases where you can't rely on the LSB functions, here's the complete function implementation:
status_of_proc() {
local pidfile daemon name status OPTIND
pidfile=
OPTIND=1
while getopts p: opt; do
case "$opt" in
p)
pidfile="$OPTARG"
;;
esac
done
shift $(($OPTIND - 1))
if [ -n "$pidfile" ]; then
pidfile="-p $pidfile"
fi
daemon="$1"
name="$2"
status="0"
pidofproc $pidfile $daemon > /dev/null || status="$?"
if [ "$status" = 0 ]; then
log_success_msg "$name is running"
return 0
else
if [ "$status" = 4 ]; then
log_failure_msg "could not access PID file for $name"
return $status
else
log_failure_msg "$name is not running"
return $status
fi
fi
}
1. Checking service status with PID file:
status_of_proc -p /var/run/nginx.pid nginx "Nginx Web Server"
2. Checking service status without PID file:
status_of_proc /usr/sbin/sshd "SSH Daemon"
If you get "function not found" errors:
- Ensure
/lib/lsb/init-functions
exists - Verify you've sourced the file with
. /lib/lsb/init-functions
- Check for proper file permissions (should be readable)
For systems without LSB functions, you can implement similar functionality:
check_service_status() {
local pidfile="$1"
local process_name="$2"
local service_name="$3"
if [ -f "$pidfile" ]; then
local pid=$(cat "$pidfile")
if ps -p "$pid" > /dev/null 2>&1; then
echo "[OK] $service_name is running (pid $pid)"
return 0
else
echo "[FAIL] $service_name pid file exists but process is not running"
return 1
fi
else
if pgrep -x "$process_name" > /dev/null; then
echo "[OK] $service_name is running"
return 0
else
echo "[FAIL] $service_name is not running"
return 1
fi
fi
}
The status_of_proc
function is a valuable utility found in Linux init scripts, particularly in Debian-based systems. This shell function isn't a built-in bash command, but rather part of the LSB (Linux Standard Base) init-functions script that gets sourced by system init scripts.
This function is typically defined in /lib/lsb/init-functions
on Debian/Ubuntu systems. The standard init script boilerplate includes:
. /lib/lsb/init-functions
This sourcing makes all LSB helper functions available to the script.
The function performs several key operations:
status_of_proc() {
local pidfile daemon name status OPTIND
pidfile=
OPTIND=1
while getopts p: opt; do
case "$opt" in
p) pidfile="$OPTARG" ;;
esac
done
shift $(($OPTIND - 1))
if [ -n "$pidfile" ]; then
pidfile="-p $pidfile"
fi
daemon="$1"
name="$2"
status="0"
pidofproc $pidfile $daemon > /dev/null || status="$?"
if [ "$status" = 0 ]; then
log_success_msg "$name is running"
return 0
else
if [ "$status" = 4 ]; then
log_failure_msg "could not access PID file for $name"
return $status
else
log_failure_msg "$name is not running"
return $status
fi
fi
}
Here's how to properly use it in your own scripts:
#!/bin/sh
### BEGIN INIT INFO
# Provides: mydaemon
# Required-Start: $network $remote_fs $syslog
# Required-Stop: $network $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: My custom daemon
### END INIT INFO
# Load LSB functions
. /lib/lsb/init-functions
DAEMON=/usr/sbin/mydaemon
NAME=mydaemon
PIDFILE=/var/run/mydaemon.pid
case "$1" in
start)
log_daemon_msg "Starting $NAME"
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON
log_end_msg $?
;;
stop)
log_daemon_msg "Stopping $NAME"
start-stop-daemon --stop --quiet --pidfile $PIDFILE --exec $DAEMON
log_end_msg $?
;;
status)
status_of_proc -p $PIDFILE $DAEMON $NAME
exit $?
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|status|restart}"
exit 1
;;
esac
exit 0
Problem: Function not found
Solution: Ensure you've sourced init-functions before calling it:
if [ -f /lib/lsb/init-functions ]; then
. /lib/lsb/init-functions
else
echo "LSB functions not available" >&2
exit 1
fi
Problem: Different path on some systems
Solution: Use this more robust sourcing approach:
for path in /lib/lsb/init-functions /etc/init.d/functions; do
[ -f "$path" ] && . "$path" && break
done
For systems without LSB support, you can define your own version:
status_of_proc() {
local pidfile="$1"
local process="$2"
local name="$3"
if [ -f "$pidfile" ]; then
local pid=$(cat "$pidfile" 2>/dev/null)
if [ -n "$pid" ] && ps -p "$pid" >/dev/null 2>&1; then
echo "$name is running with pid $pid"
return 0
else
echo "$name is not running but pid file exists"
return 1
fi
else
if pgrep -f "$process" >/dev/null; then
echo "$name is running but no pid file"
return 0
else
echo "$name is not running"
return 3
fi
fi
}
The function returns standardized exit codes:
- 0 - Process is running
- 1 - General failure
- 3 - Process not running
- 4 - Could not access PID file