Check a Process Exit with mysql_waitpid on Linux
A shutdown script sends SIGTERM and immediately moves on, with no idea whether the process actually died or is still hanging around. mysql_waitpid, oddly bundled with the MariaDB client tools, solves that one problem well: give it a PID and a wait time in seconds, and it hands back an exit status your script can act on.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes. You need a Unix-like shell and the mariadb-client package. The examples use the installed Ubuntu package version 1:10.11.14-0ubuntu0.24.04.1, whose utility reports version 1.1. No database connection is required. You should also know which account owns the process you are checking.
1. Confirm the installed name and version
Start with read-only checks. These commands do not need elevated privileges:
$ command -v mysql_waitpid
/usr/bin/mysql_waitpid
$ ls -l /usr/bin/mysql_waitpid
lrwxrwxrwx 1 root root ... /usr/bin/mysql_waitpid -> mariadb-waitpid
$ dpkg-query -W -f='${Package} ${Version}\n' mariadb-client
mariadb-client 1:10.11.14-0ubuntu0.24.04.1
$ mysql_waitpid --version
mysql_waitpid version 1.1 by Jani Tolonen
MariaDB renamed the client to mariadb-waitpid from MariaDB 10.5, while retaining mysql_waitpid as a compatibility name. On this Linux installation the old name is a symlink. Use whichever name your deployment standardises on, but do not assume both names exist on every platform.
Checkpoint
Stop here if the binary is missing or the package version is not the one you expect. Install or change packages through your normal system administration process, not through this guide.
2. Read the contract before choosing a PID
The command shape is:
mysql_waitpid [options] PID WAIT_TIME
PID and WAIT_TIME must both be positive integers. The program uses the Unix kill() system call with signal 0, then waits for the process to terminate. Signal 0 is a permission and existence probe. It does not ask the process to exit and it is not a replacement for kill, systemctl stop or a service manager.
If the process exits within the wait time, or the PID does not exist, the command returns status 0. If the process is still present when the wait expires, it returns status 1. A status of 0 therefore means that the requested end condition was observed, not that this utility terminated the process.
Signal permissions still matter. Check a process owned by the same user where possible. If the target belongs to another account, the kernel may deny the probe; using sudo can broaden access and should be an explicit operational decision. This command does not need root for ordinary same-user checks.
3. Test a process that exits normally
Use a short-lived child for a harmless smoke test. The shell records its PID, and mysql_waitpid watches it for up to three seconds:
$ sleep 1 &
$ PID=$!
$ printf 'watching PID %s\n' "$PID"
watching PID 12345
$ mysql_waitpid "$PID" 3
$ printf 'mysql_waitpid status: %s\n' "$?"
mysql_waitpid status: 0
$ wait "$PID" 2>/dev/null || true
Your PID will differ. The final wait reaps the shell child where the shell supports that distinction; it does not alter the result already returned by mysql_waitpid.
Checkpoint
Status 0 confirms that the test process was gone within the allowed interval. It does not confirm that a long-running service will stop, because this utility does not send a terminating signal.
4. Handle an absent PID
An absent process is also a successful end condition. Use a positive PID that is not currently in use on the host. A high number is only an example, so check the value in your own environment:
$ mysql_waitpid 999999 1
$ printf 'mysql_waitpid status: %s\n' "$?"
mysql_waitpid status: 0
Do not treat this result as proof that a process once existed or that a service stopped cleanly. It only says that no process matching that PID remained for the utility to wait for. PIDs are recycled, so obtain a fresh PID and check it close to the operation you are monitoring.
5. Detect a timeout without changing the process
For a process that outlives the wait, the result is status 1. This example leaves a temporary sleep running only long enough to demonstrate the boundary, then cleans it up explicitly:
$ sleep 10 &
$ PID=$!
$ mysql_waitpid "$PID" 1
$ status=$?
$ printf 'mysql_waitpid status: %s\n' "$status"
mysql_waitpid status: 1
$ kill "$PID"
$ wait "$PID" 2>/dev/null || true
Warning
The kill in this demonstration is the destructive step. Replace "$PID" only with a process you are authorised to stop. In production, use the service's documented stop and recovery procedure. If the process must remain running, omit this demonstration and leave no background test process behind.
6. Put the status in a script
Use the exit status, not the command's version or help text, as the machine-readable result. Keep the PID and timeout quoted, and reject empty variables before calling the utility:
#!/bin/sh
PID='12345'
WAIT_TIME='5'
case "$PID:$WAIT_TIME" in
*[!0-9:]*|:*)
printf '%s\n' 'PID and wait time must be positive integers' >&2
exit 2
;;
esac
if [ "$PID" -eq 0 ] || [ "$WAIT_TIME" -eq 0 ]; then
printf '%s\n' 'PID and wait time must be greater than zero' >&2
exit 2
fi
if mysql_waitpid "$PID" "$WAIT_TIME"; then
printf 'PID %s is no longer running, or was absent\n' "$PID"
else
status=$?
if [ "$status" -eq 1 ]; then
printf 'PID %s did not exit within %s seconds\n' "$PID" "$WAIT_TIME" >&2
else
printf 'mysql_waitpid failed with status %s\n' "$status" >&2
fi
exit "$status"
fi
For a fixed service PID, prefer reading the service's PID file or asking its manager rather than guessing a number.
7. Use the small option set deliberately
The installed utility has three useful option groups:
--help,-?and-Idisplay help.--verboseand-vwarn if signal 0 cannot be used and signal 1 is substituted.--versionand-Vprint version information.
There is no configuration file, database connection option or service-stop mode described by this command. If you need to stop a process, use the tool that owns its lifecycle, then use mysql_waitpid only when this wait-and-status behaviour fits the workflow.
Done means
- You confirmed which MariaDB utility and package version are installed.
- You passed a positive PID and positive wait time.
- You interpret status 0 as exited or absent, and status 1 as a timeout.
- You know that signal 0 probes a process and does not terminate it.
- Your wrapper checks the exit status and leaves no unplanned test process running.