Redhat에서 쉘 스크립트를 데몬으로 어떻게 실행할 수 있습니까?


12

필자는 기본적으로 로깅이있는 하나의 라이너 인 셸 스크립트를 가지고 있는데 init 스크립트 에서이 스크립트를 실행하려고합니다. Redhat이 사용할 수 없는 것으로 보이므로 daemon내부 함수를 사용하여 /etc/init.d/functions실행하고 start-stop-daemon있습니다. init 스크립트 ( /etc/init.d/script start)를 호출 하면 프로세스를 완료하고 실행하지 않고 포 그라운드에 유지됩니다. 이 스크립트를 데몬 화하는 올바른 방법은 무엇입니까?

실행할 스크립트 :

# conf file where variables are defined
. /etc/script.conf

echo "Starting..." | logger -i
echo "Monitoring $LOG_LOCATION." | logger -i
echo "Sending to $MONITOR_HOST:$MONITOR_PORT." | logger -i

tail -n 1 -F $LOG_LOCATION |
grep WARN --line-buffered  |
/usr/bin/nc -vv $MONITOR_HOST $MONITOR_PORT 2>&1 |
logger -i

초기화 스크립트 :

#!/bin/bash


# Source Defaults
. /etc/default/script

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

prog=/usr/local/bin/script.sh

[ -f /etc/script.conf ] || exit 1

RETVAL=0

start()
{
    # Quit if disabled
    if ! $ENABLED; then
            echo "Service Disabled in /etc/default/script"
            exit 1
    fi

    echo "Starting $prog"

    daemon $prog

    RETVAL=$?

    return $RETVAL
}

stop ()
{
    echo -n $"Stopping $prog: "
    killproc $prog

    RETVAL=$?

    return $RETVAL
}

reload()
{
    echo "Reload command is not implemented for this service."
    return $RETVAL
}

restart()
{
    stop
    start
}

condrestart()
{
    echo "Not Implemented."
}

# See how we were called.
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status $prog
        ;;
    restart)
        restart
        ;;
    reload)
        reload
        ;;
    condrestart)
        condrestart
        ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|reload}"
        RETVAL=1
esac

bash -vx를 사용한 마지막 ~ 20 줄 실행 :

+ case "$1" in
+ start
+ true
+ echo 'Starting /usr/local/bin/script.sh'
Starting /usr/local/bin/script.sh
+ daemon /usr/local/bin/script.sh
+ local gotbase= force=
+ local base= user= nice= bg= pid=
+ nicelevel=0
+ '[' /usr/local/bin/script.sh '!=' /usr/local/bin/script.sh ']'
+ '[' -z '' ']'
+ base=script.sh
+ '[' -f /var/run/script.sh.pid ']'
+ '[' -n '' -a -z '' ']'
+ ulimit -S -c 0
+ '[' -n '' ']'
+ '[' color = verbose -a -z '' ']'
+ '[' -z '' ']'
+ initlog -q -c /usr/local/bin/script.sh

bash -vx ...우리가 전경에 남아있는 것을 볼 수 있도록 스크립트를 실행 하고 마지막 줄을 게시하는 것이 유용합니다 .
Hauke ​​Laging

1
이 권리의 사용을 점점 귀찮게과 함께 가지 마세요 daemon, 거기 RPM 패키지 도. Btw에는 많은 로그 모니터링 도구가 있습니다 ( 여기서 시작하십시오 ).
sr_

Hauke, 당신은 첫 줄을 사용하는 것을 의미 #!/bin/bash -vx합니까? 이 작업을 시도했지만 쉘 스크립트를 직접 실행하는 경우와 동일한 init 스크립트 출력을 생성하지 않았습니다.
bshacklett

@bshacklett은 init 스크립트 (실제로 쉘 스크립트) 기능을로 명시 적으로 실행하여 검사 할 수 있습니다 bash -vx. bash -vx /etc/init.d/script start.
sr_ April

1
@bshacklett Wrt 로그, logstash에 대해 자세히 살펴 보겠습니다 . 저장소에는 Log4j에서 직접 로그를 제공 할 수 있지만 logstash 에이전트는 로그 파일을 모니터 할 수도 있습니다.
sr_

답변:


2

I은 스크립트 발견 http://www.linuxforums.org/forum/programming-scripting/190279-daemon-etc-init-d-functions-does-not-return-launching-process.html#post897522 내가 할 수 있었다 내 필요에 맞게 수정합니다. PID를 수동으로 추적하고를 사용하여 PID 파일을 만듭니다 pidof. 스크립트의 PID를 볼 수 없었기 pgrep때문에 이것을 사용하도록 수정해야했습니다 pidof. 수정 후 정상적으로 작동했습니다. * 참고, pgrep은 전체 스크립트 이름이 15 자 미만인 경우에만 작동하는 것 같습니다

내가 끝내었던 것은 다음과 같습니다.

#!/bin/bash
#
# 
#
# Start on runlevels 3, 4 and 5. Start late, kill early.
# chkconfig: 345 95 05
#
#
#!/bin/bash

# absolute path to executable binary
progpath='/usr/local/bin/script.sh'

# arguments to script
opts=''

# binary program name
prog=$(basename $progpath)

# pid file
pidfile="/var/run/${prog}.pid"

# make sure full path to executable binary is found
! [ -x $progpath ] && echo "$progpath: executable not found" && exit 1

eval_cmd() {
  local rc=$1
  if [ $rc -eq 0 ]; then
    echo '[  OK  ]'
  else
    echo '[FAILED]'
  fi
  return $rc
}

start() {
  # see if running
  local pids=$(pgrep $prog)

  if [ -n "$pids" ]; then
    echo "$prog (pid $pids) is already running"
    return 0
  fi
  printf "%-50s%s" "Starting $prog: " ''
  $progpath $opts &

  # save pid to file if you want
  echo $! > $pidfile

  # check again if running
  pgrep $prog >/dev/null 2>&1
  eval_cmd $?
}

stop() {
  # see if running
  local pids=$(pgrep $prog)

  if [ -z "$pids" ]; then
    echo "$prog not running"
    return 0
  fi
  printf "%-50s%s" "Stopping $prog: " ''
  rm -f $pidfile
  kill -9 $pids
  eval_cmd $?
}

status() {
  # see if running
  local pids=$(pgrep $prog)

  if [ -n "$pids" ]; then
    echo "$prog (pid $pids) is running"
  else
    echo "$prog is stopped"
  fi
}

case $1 in
  start)
    start
    ;;
  stop)
    stop
    ;;
  status)
    status
    ;;
  restart)
    stop
    sleep 1
    start
    ;;
  *)
    echo "Usage: $0 {start|stop|status|restart}"
    exit 1
esac

exit $?

0

Redhat을 모르지만 daemon $prog &이상하게 보입니다. 데몬을위한 함수가 이미 있다면 왜이 함수 자체를 백그라운드에 두어야합니까? 따라서없이 시도하십시오 &.


4
잘못이 아닙니다. 인수가 자신을 데몬 화 할 것으로 기대 /etc/init.d/functions하는 daemon함수를 정의합니다 . 사용자 변경, ulimits 설정, pidfile 확인 (생성하지 않음)과 같은 것만 처리합니다 ...이 daemon함수 의 가장 좋은 사용법은 그것을 libslack의daemon ; 으로 대체하는 것입니다 .)
sr_

죄송합니다. 문제 해결을위한 시점에 &가있었습니다. 나는이 게시물에 그것을 포함시키지 않았습니다.
bshacklett
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.