pidofprocまたはpidofはinit.dでは機能しますが、/usr/sbinでは機能しません。

pidofprocまたはpidofはinit.dでは機能しますが、/usr/sbinでは機能しません。

私がサポートするLinuxサービスがあります。一般的に使用されるstartコマンドを提供しますstop。デザイナーは、メイン機能の開始と再試行を制御するように設計されたラッパーコマンドを作成しました。ラッパーには、pidofproc自分自身を呼び出してすでに実行されていることを確認する初期チェックが含まれています。開始および停止機能もこれを確認するために使用されます。

pidofprocを呼び出した後、pidofprocを使用するinit.dプログラムの起動および停止機能には問題はありませんが、. /etc/init.d/functionsラッパーは同じように見える操作を実行できません。

もともと包装紙でいくつかの問題を発見しました。最初は呼び出さなかったfunctions。その後、戻り値を文字列として正しくテストしませんでした。また、サービススクリプトがbashスクリプトで、ラッパーがシェルであることを確認してbashに切り替えました。これらのどれも役に立ちません。

問題のMCVEを作成しました。ラッパーは実行を維持するために役に立たないwhileループを実行しますが、実際のコードと非常によく似ています。問題は、myprogすでに実行されているインスタンスがあるときに実行している場合、関数__pids_pidofの関数がから戻り値を取得できないpidofのに対し、起動スクリプトと停止スクリプトが正しく機能することをトレースで明確に示すことです。

違いは何ですか?

ラッパースクリプトの例 /usr/sbin/safe_myprog:

#!/bin/bash
set -x

PROG_NAME=myprog
INSTALL_DIR=/var/www/${PROG_NAME}
PROG=${INSTALL_DIR}/bin/${PROG_NAME}
SAFE_PROG_NAME=safe_myprog
SAFE_MYPROG=/usr/sbin/${SAFE_PROG_NAME}

message() {
   # echo "$1" >&2
   logger -t safe_myprog[$$] "$1"
}
. /etc/init.d/functions
safe_myprog=`pidofproc $SAFE_MYPROG`
if [ -n "$safe_myprog" ]; then
    if [ -n "$(ps -p $safe_myprog -o pid=)" ]; then
        message "$SAFE_PROG_NAME: is already running. pid: $safe_myprog"
        exit 0
    fi
fi

while :; do
        sleep 60
done

サービスプログラム/etc/init.d/myprog:

#!/bin/bash
set -x

# Source function library.
. /etc/init.d/functions

cd /

PROG_NAME=myprog
INSTALL_DIR=/var/www/${PROG_NAME}
SAFE_PROG_NAME=safe_myprog
SAFE_MYPROG=/usr/sbin/${SAFE_PROG_NAME}
PROG=${INSTALL_DIR}/bin/${PROG_NAME}
PROG_LOCK_FILE=/var/lock/subsys/${PROG_NAME}
PROG_PID_FILE=/var/lib/${PROG_NAME}/${PROG_NAME}.pid
RETVAL=0

txtgrn=$(tput setaf 2)
txtred=$(tput setaf 1)
txtrst=$(tput sgr0)

message() {
    if [ $RETVAL -eq 0 ]; then
        printf "%-45s[${txtgrn}  OK  ${txtrst}]\n" "$1"
    else
        printf "%-45s[${txtred}FAILED${txtrst}]\n" "$1"
    fi
}
start() {
    safe_myprog=`pidofproc $SAFE_MYPROG`
    if [ -n "${safe_myprog}" ]; then
         message $"$SAFE_PROG_NAME: is already running. pid: $safe_myprog"
         return 0
    fi

    #$SAFE_MYPROG > /dev/null 2>&1
    $SAFE_MYPROG &
    RETVAL=$?
    message $"Starting $PROG_NAME: "
    if [ $RETVAL -eq 0 ]; then
        touch $PROG_LOCK_FILE
    fi
    return $RETVAL
}
stop() {
    safe_myprog=`pidofproc $SAFE_MYPROG`
    if [ -n "${safe_myprog}" ]; then
        /bin/kill $safe_myprog
    fi
    if [ -e $PROG_PID_FILE ]; then
        pid=$(cat $PROG_PID_FILE)
        if [ -n "$(ps -p $pid -o pid=)" ]; then
            /bin/kill -9 "$pid"
            RETVAL=$?
            #if [ $# -eq 0 ]; then
                message "Stopping $PROG_NAME: pid: $pid"
            #fi
        else
            #if [ $# -eq 0 ]; then
                message "$PROG_NAME is already stopped."
            #fi
            /bin/rm -f $PROG_PID_FILE
            RETVAL=0
        fi
    fi
    if [ -f $PROG_PID_FILE ]; then
        /bin/rm -f $PROG_PID_FILE
    fi
    if [ -e $PROG_LOCK_FILE ]; then
        /bin/rm -f $PROG_LOCK_FILE
    fi
    return $RETVAL
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
esac
exit $RETVAL

この操作を 2 回実行したservice myprog start後に safe_myprog を直接実行すると、safe_myprog トレース出力の主な部分は次のとおりです。

++ __pids_pidof /usr/sbin/safe_myprog
++ pidof -c -m -o 14454 -o 30619 -o %PPID -x /usr/sbin/safe_myprog
++ pidof -c -m -o 14454 -o 30619 -o %PPID -x safe_myprog
++ return 3
+ safe_myprog=
+ '[' -n '' ']'

startへの2番目の呼び出しは同じ関数呼び出しの出力であるように見えますが、次のようになります。

++ __pids_pidof /usr/sbin/safe_myprog
++ pidof -c -m -o 14406 -o 14399 -o %PPID -x /usr/sbin/safe_myprog
+ safe_myprog=14339
+ '[' -n 14339 ']'
+ message 'safe_myprog: is already running. pid: 14339'

pidof -c -m -o 14454 -o 30619 -o %PPID -x /usr/sbin/safe_myprogコマンドラインから実行すると(実行後functions)正解が与えられます。

この関数を使用するラッパーシェルは、この関数を使用するinit.dシェルとどのように比較され、具体的にpidofprocなぜpidof他の答えを提供するのでしょうか。

関連情報