サービスがスクリプトで実行されているかどうかをテストする「正しい」方法

サービスがスクリプトで実行されているかどうかをテストする「正しい」方法

私の質問:

指定されたサービスが実行されていることを確認するbashスクリプトを作成しています。

を使用して手動で行う方法を知っています$ service [service_name] status

ただし、(特にsystemdに切り替えた後)、解析するために少し混乱している多くのテキストが印刷されます。単純な出力または確認できる戻り値を持つスクリプトに対するコマンドがあるとします。

しかし、Googleで検索すると「ああ、ただ」という結果がたくさん出ますps aux | grep -v grep | grep [service_name]。それはベストプラクティスではありませんか?コマンドの他のインスタンスが実行されているがSysV initスクリプトによって起動されたインスタンスではない場合はどうなりますか?

それとも、ちょうど黙って少しpgrepで手を汚す必要がありますか?

答え1

systemctl一つあるis-activeこれに対するサブコマンド:

systemctl is-active --quiet service

アクティブな場合はステータス0で終了し、serviceそれ以外の場合はゼロ以外で終了するため、スクリプトに最適です。

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

省略すると、--quiet現在の状態も標準出力に出力されます。

一部のユニットは、サービスを提供するために実行されているものが何もなくてもアクティブになることがあります。 「RemainAfterExit」と表示されたユニットは、正常に終了するとアクティブと見なされます。アイデアは、デーモンが不要なサービスを提供することです(例えばシステムの特定の側面を構成します。ただし、デーモンに関連するデバイスは、デーモンが継続して実行されている間にのみアクティブになります。

使い捨てデバイスいいえ「RemainAfterExit」はアクティブなユニット状態に入らないため、is-activeこれらのユニットの処理に成功しません。is-activeテキスト出力を解析できます。

systemctl is-active service

現在実行中の使い捨てデバイスについては「有効」、現在実行中ではないが最後に正常に実行された(ある場合)使い捨てデバイスについては「無効」、現在実行されていない使い捨てデバイスについては「失敗」を出力します。実行中で、最後に実行したときに失敗しました。is-activeこれらのユニットは常にゼロ以外の状態を返すので、次のように実行します。

systemctl is-active service ||:

必要に応じて無視してください。

答え2

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 "=".

サービスの利用可能なプロパティを表示するには、次のようにしますpolkit

systemctl show -a polkit

LoadState残念ながら、ActiveStateおよびの可能な値はSubStateマンページに文書化されておらず、代わりにD-Busインターフェース記述に文書化されていますorg.freedesktop.systemd1https://www.freedesktop.org/software/systemd/man/org.freedesktop.systemd1.html

LoadStateデバイスの構成ファイルがロードされたかどうかを反映するステータス値を含みます。現在定義されている状態は " loaded"、" error"、および" masked"です。 " loaded"は設定が正常にロードされたことを示します。 " error"は設定のロードに失敗したことを示します。このLoadErrorフィールド(以下を参照)には、この失敗の原因に関する情報が含まれています。 " masked"は、その単位が現在マスクされていることを示します(つまり、シンボリックリンクされているか空/dev/nullです)。有効なロードされた構成を持たないデバイスがアクティブになる可能性があるため(以下を参照)LoadStateと完全に直交します(ActiveStateデバイスがすでにアクティブになっている間に構成が再ロードされた可能性があるため)。

ActiveStateデバイスが現在アクティブであるかどうかを反映するステータス値を含みます。現在定義されている状態は、" active"、" reloading" inactive、""、" failed"、" activating"、" deactivating"です。 " active"は、デバイスが有効になっていることを意味します(明らかに...)。 " reloading"は、デバイスがアクティブであり、現在の設定をリロードしていることを示します。 " inactive" は非アクティブで、以前の実行が成功したか、以前の実行がまだ発生していないことを意味します。 " failed"は非アクティブであり、以前の実行が成功しなかったことを意味します(これについての詳細は、結果属性のサービスなど、デバイスタイプ固有のインターフェイスにあります。以下を参照)。 " activating"は、そのデバイスが以前に非アクティブであったが現在アクティブであることを示します。一方、" deactivating"は、そのデバイスが現在無効になっていることを示します。

SubStateActiveStateセルタイプに関連するよりきめ細かい状態をオーバーライドしますが、理解している同じ状態マシンの状態をエンコードします。ActiveState6つの上位レベルの状態のみを扱い、SubState6つの上位レベルの状態にマッピングされているより多くの下位レベルのユニットタイプ固有の状態を扱うことができます。複数の下位レベルの状態を同じ上位レベルの状態にマッピングできますが、その逆は不可能です。すべての上位レベルの状態がすべての単位タイプに対して下位レベルの状態を持つわけではありません。現在、下位レベルの状態はここでは文書化されておらず、上記の一般的な上位レベルの状態よりも後で拡張される可能性が高いです。

そこには多くの不動産があるので、あなたが探しているものが何であるかを知っていれば...

$ systemctl show - polkit | grep Active
ActiveState=active
ActiveEnterTimestamp=Thu 2020-07-02 07:24:40 IST
ActiveEnterTimestampMonotonic=6682102
ActiveExitTimestamp=
ActiveExitTimestampMonotonic=0

答え3

Zannaの答えを補うために--valueオプションが導入されました。systemctl showシステムバージョン230。したがって、一部のディストリビューション(debian jessieなど)では使用できない場合があります。

この場合、sedを使用してこのオプションをエミュレートできます。

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

答え4

コマンドラインの実行やスクリプトの作成時にこれが役に立つと思います。

@StephenKittからコピーしました

サービスがダウンしていることを確認し、サービスを再起動します。

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

ここで、||systemctlの戻り値がゼロでないことを確認します。つまり、作成者が説明したようにアクティブになっていないことを意味します。

関連情報