更新された回答

更新された回答

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

関連情報