쉘 스크립트에 대한 서비스를 작성하여 디먼처럼 시작하고 중지 할 수 있습니까?


22

CentOS 7을 사용하고 있습니다 .5 초마다 cron을 만드는 것이 목표입니다.하지만 연구하면서 cron을 1 분만 사용할 수 있으므로 지금하고있는 것은 쉘 파일을 만들었습니다.
hit.sh

while sleep 5; do curl http://localhost/test.php; done

마우스 오른쪽 버튼을 클릭하여 수동으로 쳤습니다.

내가 원하는 것은 파일을 자동으로 시작하고 중지 할 수 있도록 해당 파일에 대한 서비스를 만드는 것입니다.

서비스를 생성하는 스크립트를 찾았습니다

#!/bin/bash
# chkconfig: 2345 20 80
# description: Description comes here....

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

start() {
    # code to start app comes here 
    # example: daemon program_name &
}

stop() {
    # code to stop app comes here 
    # example: killproc program_name
}

case "$1" in 
    start)
       start
       ;;
    stop)
       stop
       ;;
    restart)
       stop
       start
       ;;
    status)
       # code to check status of app comes here 
       # example: status program_name
       ;;
    *)
       echo "Usage: $0 {start|stop|status|restart}"
esac

exit 0 

그러나 start 또는 stop 메소드에 무엇을 써야할지 모르겠지만 hit.sh의 동일한 내용을 배치하려고 시도했지만 stop 메소드에 start(){}오류가 발생했습니다 }.


/usr/bin/myscript자체적으로 실행할 때 제대로 작동 합니까 ? echo $?스크립트가 실행을 완료했을 때 의 결과는 무엇입니까 ? 203입니까?
Alexander

@Alexander /usr/bin/myscript.sh는 터미널을 통한 실행에서 잘 작동하고 echo$?나에게 주었다1
codegasmer

문제가 없으면 스크립트는 오류 코드 0을 반환해야합니다. 오류 코드 1은 오류를 나타냅니다.
Alexander

답변:


30

코드 샘플을 재사용하려면 다음과 같이 보일 수 있습니다.

#!/bin/bash

case "$1" in 
start)
   /path/to/hit.sh &
   echo $!>/var/run/hit.pid
   ;;
stop)
   kill `cat /var/run/hit.pid`
   rm /var/run/hit.pid
   ;;
restart)
   $0 stop
   $0 start
   ;;
status)
   if [ -e /var/run/hit.pid ]; then
      echo hit.sh is running, pid=`cat /var/run/hit.pid`
   else
      echo hit.sh is NOT running
      exit 1
   fi
   ;;
*)
   echo "Usage: $0 {start|stop|status|restart}"
esac

exit 0 

당연히 서비스로 실행하려는 스크립트는 예를 들어 /usr/local/bin/hit.sh위의 코드는로 가야합니다 /etc/init.d/hitservice.

이 서비스를 실행해야하는 각 런레벨에 대해 각각의 심볼릭 링크를 만들어야합니다. 예를 들어, 이름 /etc/init.d/rc5.d/S99hitservice이 지정된 심볼릭 링크 는 실행 수준 5의 서비스를 시작합니다. 물론 service hitservice start/ 를 통해 수동으로 시작하고 중지 할 수 있습니다.service hitservice stop


파일에 hitservice.service와 같은 접미사가 필요합니까? 이후 : backupservice.service를 시작하지 못했습니다 : 장치를 찾을 수 없습니다. CentOS 7에서 이것이 왜 대답으로 제안
되었는가

@ Code.IT OP는 스크립트가 아닌 SystemV 스크립트를 원 systemd하므로 접미사가 필요하지 않습니다. systemd그래도 예전 스크립트를 실행할 수 있어야합니다 . 시도 했습니까 systemctl enable hitservice?
Dmitry Grigoryev

@DmitryGrigoryev :이 스크립트는 다중 인스턴스를 막거나 생성 된 모든 다중 인스턴스를 중지하지 않으며, pidfile 은 마지막 pid의 생성 된 프로세스 만 저장합니다.
Luciano

27

CentOS 7 이상은 systemd를 사용한다고 생각합니다. 시스템에 해당하는 경우 다음을 시도하십시오.

  1. 실행할 스크립트 명령을 배치하십시오 /usr/bin/myscript.

  2. 로 스크립트를 실행 가능하게 만들어야합니다 chmod +x.

  3. 다음 파일을 작성하십시오.

/etc/systemd/system/my.service

[Unit]
Description=My Script

[Service]
Type=forking
ExecStart=/usr/bin/myscript

[Install]
WantedBy=multi-user.target
  1. 모든 시스템 서비스 파일을 다시로드하십시오. systemctl daemon-reload

  2. 로 서비스를 시작하여 작동하는지 확인하십시오 systemctl start my.

보너스:

시스템 서비스를 테스트하기 위해 두 개의 창 분할 창이있는 tmux 환경을 시작할 수 있습니다. 여기서 상단 창은 스크립트의 출력 ( stdoutstderr)을 모니터 하고 하단 창은 서비스를 다시 시작하는 데 사용될 수 있습니다. 이를 tmux설치 한 후 간단히 다음을 수행 해야 합니다.

tmux new-session \; select-layout even-horizontal \; split-window -v journalctl -o cat --since=@$(date +%s) -f -u my \; rotate-window \; set -g status-bg colour0 \; set -g status-fg colour9 \; attach

그런 다음 다음을 사용하여 서비스를 다시 시작하십시오.

systemctl restart my

종료 tmuxctrl-d다음 ctrl-c.


답장을 보내 주셔서 감사합니다. 솔루션을 시도했지만 서비스가 시작되지 않습니다. 자세한 내용을 추가 한 내 질문을 볼 수 있습니까
codegasmer

스크립트가 실패하지는 않지만 작동하지만 오류 코드 0을 반환한다고 생각합니다.
Alexander

4
이제 나는 체계적입니다!
DenisKolodin

1
시스템 서비스가 액세스하여 실행할 수있는 한 스크립트를 어느 곳에 나 배치 할 수 있습니다.
Alexander

2
추천하지 않습니다 Type=forking. 기회는 아스 커는 필요하다 Type=simple그러나 일반적으로 포크 (fork)에 사용하지 않는 것이 좋습니다 : 0pointer.de/public/systemd-man/... . 사람들은 오래된 init 스크립트를 가져 와서 systemd서비스 시작을 위해 감싸고 있습니다 systemd(init-script(service)). 그러나 systemdinit 스크립트를 대체 systemd하므로 다음과 같이 서비스를 직접 호출해야합니다 systemd(service).
Centimane

3

이것은 서비스로서의 스크립트입니다.

[Unit]
Description=To change In test buffer
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/test.sh
TimeoutStartSec=0

[Install]
WantedBy=default.target


0

Bash Service Manager 프로젝트 참조 : https://github.com/reduardo7/bash-service-manager

구현 예

#!/usr/bin/env bash

export PID_FILE_PATH="/tmp/my-service.pid"
export LOG_FILE_PATH="/tmp/my-service.log"
export LOG_ERROR_FILE_PATH="/tmp/my-service.error.log"

. ./services.sh

run-script() {
  local action="$1" # Action

  while true; do
    echo "@@@ Running action '${action}'"
    echo foo
    echo bar >&2

    [ "$action" = "run" ] && return 0
    sleep 5
    [ "$action" = "debug" ] && exit 25
  done
}

before-start() {
  local action="$1" # Action

  echo "* Starting with $action"
}

after-finish() {
  local action="$1" # Action
  local serviceExitCode=$2 # Service exit code

  echo "* Finish with $action. Exit code: $serviceExitCode"
}

action="$1"
serviceName="Example Service"

serviceMenu "$action" "$serviceName" run-script "$workDir" before-start after-finish

사용 예

$ ./example-service
# Actions: [start|stop|restart|status|run|debug|tail(-[log|error])]

$ ./example-service start
# Starting Example Service service...

$ ./example-service status
# Serive Example Service is runnig with PID 5599

$ ./example-service stop
# Stopping Example Service...

$ ./example-service status
# Service Example Service is not running
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.