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一致するセル*が1つ以上ある場合に"$systemd_unit_name"
返されます。終了ステータス1。
*注:systemctl list-unit-files ...
リストにないようです。機器単位( .device
)。
更新された1行
これらの(最新の)オネライナは、サービスデバイス、ターゲットデバイス、ソケットデバイスなど、あらゆる種類のデバイスの存在をテストできます。またテンプレート単位(例[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
指定したデバイス名は不明です。システム(つまり、要求されたユニットは存在しません。)
欠陥のある1行
# 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