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