From 9ff59e6c4bc09b0252810b709bd5f6aa35f76691 Mon Sep 17 00:00:00 2001 From: Liam Crilly Date: Thu, 1 Jun 2023 17:53:12 +0100 Subject: [PATCH] Tools: improved ps(1) portability for unitc. Improved cross-platform support by trying multiple ps(1) invocations to obtain the unitd command line parameters. Additional error checking detects when this process fails. The first attempt uses `ps -wwo args=COMMAND -p` which has very broad support and has the additional benefit of simplifying the output for more reliable parsing of the process info. If that fails then we fall back to simply `ps`. The parsing of the process info has also changed. Instead of converting '[]' into spaces we now convert them into explicit delimiters (using '^'). This is more reliable as it marks the beginning and the end of the info we care about. Any trailing process information is now ignored (FreeBSD). Additional error handling improves the robustness when starting unitd with a different filename or from a relative path. In this case the control socket and log file detection will fail when running `unitd --help`. Additional error checking and messages are displayed when the control socket cannot be determined. A single warning is shown when the log file cannot be determined. --- tools/unitc | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/tools/unitc b/tools/unitc index 9e398a7a..ee355257 100755 --- a/tools/unitc +++ b/tools/unitc @@ -129,12 +129,23 @@ if [ $REMOTE -eq 0 ]; then exit 1 fi - # Get control address + # Obtain any optional startup parameters from the 'unitd: main' process + # so we can get the actual control address and error log location. + # Command line options and output of ps(1) is notoriously variable across + # different *nix/BSD platforms so multiple attempts might be needed. # - PARAMS=$(ps $PID | grep unitd | cut -f2- -dv | tr '[]' ' ' | cut -f3- -d ' ' | sed -e 's/ --/\n--/g') + PARAMS=$((ps -wwo args=COMMAND -p $PID || ps $PID) 2> /dev/null | grep unit | tr '[]' ^ | cut -f2 -d^ | sed -e 's/ --/\n--/g') + if [ "$PARAMS" = "" ]; then + echo "${0##*/}: WARNING: unable to identify unitd command line parameters for PID $PID, assuming unitd defaults from \$PATH" + PARAMS=unitd + fi CTRL_ADDR=$(echo "$PARAMS" | grep '\--control' | cut -f2 -d' ') if [ "$CTRL_ADDR" = "" ]; then - CTRL_ADDR=$($(echo "$PARAMS" | grep unitd) --help | grep -A1 '\--control' | tail -1 | cut -f2 -d\") + CTRL_ADDR=$($(echo "$PARAMS") --help | grep -A1 '\--control' | tail -1 | cut -f2 -d\") + fi + if [ "$CTRL_ADDR" = "" ]; then + echo "${0##*/}: ERROR: cannot detect control socket. Did you start unitd with a relative path? Try starting unitd with --control option." + exit 2 fi # Prepare for network or Unix socket addressing @@ -156,7 +167,11 @@ if [ $REMOTE -eq 0 ]; then # ERROR_LOG=$(echo "$PARAMS" | grep '\--log' | cut -f2 -d' ') if [ "$ERROR_LOG" = "" ]; then - ERROR_LOG=$($(echo "$PARAMS" | grep unitd) --help | grep -A1 '\--log' | tail -1 | cut -f2 -d\") + ERROR_LOG=$($(echo "$PARAMS") --help | grep -A1 '\--log' | tail -1 | cut -f2 -d\") + fi + if [ "$ERROR_LOG" = "" ]; then + echo "${0##*/}: WARNING: cannot detect unit log file (will not be monitored). If you started unitd from a relative path then try using the --log option." + ERROR_LOG=/dev/null fi # Cache the discovery for this unit PID (and cleanup any old files)