제가 지원하는 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
이 작업을 두 번 수행 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에 대한 두 번째 호출은 동일한 함수 호출의 출력인 것처럼 보이지만 다음과 같습니다.
++ __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
다른 답변을 제공하는 것처럼 보입니까?