서비스가 스크립트에서 실행 중인지 테스트하는 "적절한"방법


96

내 문제:

bash 스크립트를 작성 중이며 주어진 서비스가 실행되고 있는지 확인하고 싶습니다.

이 작업을 수동으로 수행하는 방법을 알고 있습니다 $ service [service_name] status.

그러나 (특히 systemd로 이동 한 이후) 구문 분석하기가 약간 까다로운 전체 텍스트를 인쇄합니다. 간단한 출력 또는 확인할 수있는 반환 값을 가진 스크립트에 대한 명령이 있다고 가정했습니다.

그러나 인터넷 검색은 단지 "아, 그냥 ps aux | grep -v grep | grep [service_name]"결과 의 톤을 산출합니다 . 그것은 최선의 방법이 될 수 없습니까? 해당 명령의 다른 인스턴스가 실행 중이지만 SysV init 스크립트에 의해 시작되지 않은 경우 어떻게됩니까?

아니면 그냥 닥치고 작은 pgrep로 손을 더럽혀 야합니까?

답변:


139

systemctl이에 대한 is-active부속 명령이 있습니다.

systemctl is-active --quiet service

service활성화 되면 상태 0으로 종료하고 그렇지 않으면 0이 아니므로 스크립트에 이상적입니다.

systemctl is-active --quiet service && echo Service is running

생략 --quiet하면 현재 상태도 표준 출력으로 출력됩니다.

don_crissti가 지적한 바와 같이 , 서비스를 제공하기 위해 아무것도 실행되고 있지 않더라도 일부 장치는 활성화 될 수 있습니다.“RemainAfterExit”로 표시된 장치는 성공적으로 종료되면 활성화 된 것으로 간주됩니다 (데몬이 필요없는 서비스를 제공한다는 아이디어) ( 예 : 시스템의 일부 측면을 구성합니다). 그러나 데몬과 관련된 장치는 데몬이 여전히 실행중인 경우에만 활성화됩니다.


원샷 서비스에주의하십시오. 그들은 단독으로 inactive또는 activating둘 다 systemctl status이며 systemctl is-active3으로 종료합니다. ( systemd-241 기준 ) 해결책 :systemctl show service | grep -qx ActiveStatus=activating
Alois Mahdal

@Alois 원샷 서비스를 활성화하려는 곳에서 어떤 시나리오를 경험했는지 궁금합니다. 예가 있습니까?
스티븐 키트

물론 @StephenKitt. 도구 foo는 재부팅과 관련된 시스템 작업 foo_cleanup을 수행하고 다음 부팅시 정리 작업을 위해 원샷 서비스를 사용 합니다. 나는 이것을 테스트하고 있는데 (내 스크립트는 서비스로 예약되어있다) 나중에 오류를 수집하고 싶지만 나중에 언제 (vsauce 음악)? 기준 중 하나 foo_cleanup는 완료된 것입니다 ( "중지됨").
Alois Mahdal

'실패'도 옵션이며 시작되지 않은 서비스를 기반으로 작업을 수행해야하는 경우 유용합니다.
힐 힐리

33

systemctl스크립팅에 적합한 모드가 있습니다. show대신에 사용 status하고 -p/ --properties--value옵션을 추가하여 원하는 출력 만 얻으십시오.

다음은 Ubuntu 17.04 시스템의 예입니다.

$ systemctl show -p SubState --value NetworkManager
running

달리기 (또는 달리)는입니다 SubState. 서비스가 활성화되어 있는지 확인하려면이 속성을 사용하십시오.ActiveState

$ systemctl show -p ActiveState --value x11-common
inactive
$ systemctl show -p SubState --value x11-common
dead

의 메모 man:

show [PATTERN...|JOB...]
           Show properties of one or more units, jobs, or the manager
           itself. If no argument is specified, properties of the
           manager will be shown. If a unit name is specified, properties
           of the unit are shown, and if a job ID is specified,
           properties of the job are shown. By default, empty properties
           are suppressed. Use --all to show those too. To select specific
           properties to show, use --property=. This command is intended
           to be used whenever computer-parsable output is required. Use
           status if you are looking for formatted human-readable output.

-p, --property=
           When showing unit/job/manager properties with the show command,
           limit display to properties specified in the argument. The
           argument should be a comma-separated list of property names,
           such as "MainPID". Unless specified, all known properties are
           shown. If specified more than once, all properties with the
           specified names are shown. Shell completion is implemented for
           property names.

--value
           When printing properties with show, only print the value, and
           skip the property name and "=".

2
정교한 답변 +1. --versionsystemctl과 함께 옵션을 허용하는 배포판을 친절하게 지정하십시오 .
SK Venkat

11

Zanna의 답변을 보완하기 위해에 대한 --value옵션 이 systemd 버전 230에systemctl show 도입되었습니다 . 따라서 데비안 제시와 같은 특정 배포판에서는 사용할 수 없습니다.

이 경우 sed를 사용하여 옵션을 에뮬레이션 할 수 있습니다.

$ systemctl show -p ActiveState sshd | sed 's/ActiveState=//g'
active
$ systemctl show -p SubState sshd | sed 's/SubState=//g'  
running

1
작동하지 않을 --value 소개 버전 및 배포판을 지적하면 +1입니다.
SK Venkat

3

나는 이것이 명령 줄 실행이나 스크립트를 만드는 데 유용하다는 것을 알았습니다.

@StephenKitt에서 복사 함

서비스가 다운되었는지 확인하고 서비스를 다시 시작합니다.

systemctl is-active --quiet <service name> || <service name> restart

||systemctl 반환 값은 작성자 바와 같이 활성 상태가 아니라면 비 - 제로 의미가 있는지 검사한다.


`is-failed '를 사용하여 재시작이 필요한지 테스트 할 수도 있습니다. 실패한 서비스를 다시 시작하는 것이 조금 더 직관적 인 것 같습니다.
힐 힐리

예, 그러나 저에게는 .. 나는 스스로 연습하고 싶지 않았을 때 모든 것이 돌아가고 있다고 가정했습니다. 그래서 나는 물건으로 다른 물건을 확인할 수 있습니다. 단순히 실행 중이 아닌지 확인하려면 '실패'가 올바른 선택입니다. :)
별표

3


나는 그러나 systemctl을 사용하고 활성와 함께 파티에 너무 늦게입니다 &&||않을 경우 모든 시간이 될 스크립트에서이에. 아래는 바람둥이에 사용 된 방법이지만 여러 서비스를 확인해야하지만 여기서 범위를 벗어난 경우 인수를 사용하고 서비스 이름을 인수로 전달하는 방법에서 사용할 수 있습니다.

STATUS=`systemctl is-active tomcat.service`
  if [[ ${STATUS} == 'active' ]]; then
    echo "Execute your tasks ....."
  else 
    echo " Service not running.... so exiting "  
    exit 1  
  fi

이것이 내가 이용하는 방법입니다 .. 단지 내 것을 공유합니다.

간단하고 쉬운 것들을 위해 여기에 설명 된 다른 것들을 따르십시오.

systemctl -q is-active tomcat.service  && echo "Tomcat Runnung" || echo "Service is not running at all "

그것은 단순히 어떻게하는 것보다 낫 if systemctl is-active --quiet tomcat.service습니까? 또한 [[표준 쉘이 아닙니다.
Toby Speight

@TobySpeight 내 게시물에서 언급했듯이 "이것은 내가 사용하는 방법입니다 .... 단지 내 공유"입니다. 나는 표준 쉘 사용법을 말하지 않았다. 단일 브라켓으로 만들면 그때가 될 것이지만 여기서는 범위를 벗어난다. 또한 아래에서는 &&and를 사용하여 쉽게 수행 할 수있는 단일 행 사용법을 언급 ||합니다.
SAGAR Nair

2

Oxmel의 답변에서와 같이 sed 명령을 사용하는 대신 cut -d'=' -f 2쿼리되는 모든 종류의 속성 에 사용하면 충분합니다 .

예를 들면 다음과 같습니다.

$ systemctl show -p ActiveState sshd | cut -d'=' -f2
active
$ systemctl show -p SubState sshd | cut -d'=' -f2
running

훌륭하지만 실제로 해당 명령이 수행하는 작업에 대한 설명이 필요합니다.
힐 힐리

-1

이 위대한 작은 스크립트를 발견했습니다.

#!/bin/bash
service=replace_me_with_a_valid_service

if (( $(ps -ef | grep -v grep | grep $service | wc -l) > 0 ))
then
  echo "$service is running!!!"
else
  /etc/init.d/$service start
fi

출처


모든 서비스에 동일한 이름의 실행 파일이있는 것은 아니며 모든 사용자가 실수로 일치하는 명령을 실행할 수 있습니다. 이는 재난을위한 레시피입니다.
Toby Speight
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.