업데이트된 답변

업데이트된 답변

systemd특정 단위가 존재하는지 알고 싶습니다 .

이는 다음과 같은 경우에 작동합니다.

  • 모든 유형의 장치(서비스, 대상, 설치...)
  • 실행 중이거나 비활성화되거나 차단된 장치

나는 이것을 할 수 있다는 것을 안다:

systemctl list-unit-files | grep "^my.target"

하지만 더 나은 방법이 있어야 할 것 같았습니다.

또는 다음을 지정하여 이 검사를 실행하고 싶습니다.내 거systemctl다른 명령 과 마찬가지로 ".service"를 지정할 필요가 없습니다 .

systemctl exists my

답변1

나는 이것을 수행하는 기본 시스템 방법을 모르지만 다음을 (남용) 사용할 수 있습니다 systemctl list-unit-files.

systemctl-exists() {
  [ $(systemctl list-unit-files "${1}*" | wc -l) -gt 3 ]
}

이렇게 하면 다음과 같이 사용할 수 있는 "테스트" 함수가 생성됩니다.

systemctl-exists my && echo my exists as a systemd unit

접미사를 사용하면 *systemd가 지정된 인수를 모든 "유형"(서비스, 대상 또는 설치)과 일치시킬 수 있습니다. 이 함수는 systemctl list-unit-files일치하는 단위가 없을 때 최소 3줄의 출력을 포함하는 현재 출력으로 하드 코딩됩니다 .

1. UNIT FILE            STATE
   (one or more matching unit files)
2. (a blank line)
3. "%d unit files listed."

또한 유사한 접두사가 있는 유닛 파일이 있는 경우 끝에 있는 와일드카드는 잘못된 긍정을 유발할 수 있습니다. "au"를 검색하면 "auditd", "autofs" 등이 포함된 바보 같은 정보를 찾을 수 있습니다. 진짜 "au.service". 알고 계시다면 더 많은 서비스 이름을 알려주세요. 그러면 systemctl-exists au.service올바른 일을 할 것입니다.

systemctl cat처음에는 필터로 사용할 수 있다고 생각했지만 분명히 인수는 다음과 같다고 가정합니다.제공하다따라서 다른 유형(예: 대상 또는 설치)은 적절하게 필터링할 수 없습니다.

답변2

업데이트된 답변

분명히, 은 systemctl list-unit-files "$systemd_unit_name"(는) 반환됩니다.종료 상태 0일치하는 셀*이 하나 이상 있으면 "$systemd_unit_name"반환됩니다.종료 상태 1.

*참고: systemctl list-unit-files ...목록에 없는 것 같습니다.장비단위( .device).

업데이트된 한 줄짜리

이러한 (최신) oneliner는 서비스 장치, 대상 장치, 소켓 장치를 포함한 모든 유형의 장치 존재를 테스트할 수 있습니다.또한템플릿 단위(예: [email protected]) 및 템플릿 인스턴스 단위(예: [email protected]).

### exact non-device unit existence test
### test if some unit (not including device units) named 'foo.service' exists:

systemctl list-unit-files foo.service &>/dev/null && echo "this unit exists" || echo "this unit does not exist"


### pattern match non-devixe unit existence test
### test if at least one unit (not including device units) with a name matching 'ssh*' exists:

systemctl list-unit-files ssh* &>/dev/null && echo "at least one unit matches" || echo "no unit matches"

장비 단위의 경우 systemctl status이 명령을 사용합니다. 하지만systemctl문서에는 0종료 상태가 3단위가 있음을 의미하고 종료 상태는 4"해당 단위가 없음"을 의미한다고 언급되어 있습니다..device, 특히 로 끝나는 이름 의 경우 systemctl status doesntexist.device종료 상태가 여전히 반환되는 것을 확인했습니다 3. 따라서 다음 장치 단위별 테스트에서는 종료 상태를 0지정된 장치 단위가 존재한다는 표시로 처리합니다.

### exact device unit existence test
# test if some device unit named 'sys-module-fuse.device' exists:

systemctl status sys-module-fuse.device &>/dev/null && echo "this device unit exists" || echo "this device unit does not exist"

잘못된 답변

(적어도시스템 버전 247, 이 답변의 이전 버전은 테스트 시 신뢰할 수 없는 결과를 제공했습니다.템플릿 단위또는템플릿 단위 인스턴스(즉, 유닛 이름은 @,[1] [2]))

systemctl종료 상태가 다음 인 경우 4지정된 장치 이름을 알 수 없습니다.체계(즉, 요청한 단위가 존재하지 않습니다.)

결함이 있는 한 줄

# example oneliner to test on the existence of some unit named 'foo.service':
# !!! DOES NO WORK RELIABLY FOR TEMPLATE UNITS OR TEMPLATE UNIT INSTANCES

systemctl status foo.service &>/dev/null; if [[ $? == 4 ]]; then echo "this unit does not exist"; else echo "this unit exists"; fi

결함이 있는 Bash 스크립트

#!/bin/bash
set -euo pipefail

# file test-systemd-unit-existence.sh
#
# this script tests if there exists a systemd system unit under the provided name.
#
# !!! DOES NO WORK RELIABLY FOR TEMPLATE UNITS OR TEMPLATE UNIT INSTANCES
#
# if it exists, this script echoes "'$SYSTEMD_UNIT' exists under the full unit name '$SYSTEMD_UNIT_FULL_NAME'",
# otherwise ("unit unknown"/"no such unit") echoes "'$SYSTEMD_UNIT' does not exist".
#
# the test is accomplished by executing "systemctl status $SYSTEMD_UNIT",
# then checking its exit status
#
# see https://www.freedesktop.org/software/systemd/man/systemctl.html#Exit%20status
#
# usage examples:
# ./test-systemd-unit-existence.sh ssh.service
# ./test-systemd-unit-existence.sh ssh
# ./test-systemd-unit-existence.sh basic.target
# ./test-systemd-unit-existence.sh doesntexist.service
# ./test-systemd-unit-existence.sh uuidd
# ./test-systemd-unit-existence.sh uuidd.service
# ./test-systemd-unit-existence.sh uuidd.socket
# ./test-systemd-unit-existence.sh uuidd.target

SYSTEMD_UNIT="$1"

# using "&>/dev/null" to discard stdout and stderr output ("--quiet" only discards stdout).
# due to "set -e", using " ... && true" construct to avoid script from
# exiting immediately on expectable nonzero exit code.
#
#   "[...] The shell does not exit if the command that fails is
#    [...] part of any command executed in a && or || list
#    [as long as it isn't the final command in this list]"
#
# see https://www.gnu.org/software/bash/manual/html_node/Lists.html
# see "-e" at https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html

systemctl status "$SYSTEMD_UNIT" &>/dev/null && true
SYSTEMCTL_EXIT_STATUS="$?"

if [[ "$SYSTEMCTL_EXIT_STATUS" == 4 ]]; then
  echo "'${SYSTEMD_UNIT}' does not exist"
else
  SYSTEMD_UNIT_FULL_NAME="$(systemctl show ${SYSTEMD_UNIT} --property=Id --value)"
  echo "'${SYSTEMD_UNIT}' exists under the full unit name '${SYSTEMD_UNIT_FULL_NAME}'"
fi

관련 정보