コマンド置換で「systemctl status」を処理するのはなぜですか?

コマンド置換で「systemctl status」を処理するのはなぜですか?

スクリプトでsystemctl status出力を処理する奇妙な方法が見つかりました。

echo "$(systemctl status the_unit_name)" | grep -q 'Active: active'

明らかなものではなく:

systemctl status the_unit_name | grep -q 'Active: active'

このアプローチを使用すべき妥当な理由が見つかりません。私が欠けた理由はありますか?

答え1

systemctl(周辺設定に応じて)無視される可能性があるシャットダウン状態に加えて、他の理由はありません。なぜコマンドをこのように書いたのかを説明する歴史的要因があるかもしれませんが、これを維持する理由はありません。

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

答え2

一般的に言えば、echo "$(foo)"は愚かでjustとほぼ同じですfoo。違いは、コマンドの置き換えは、出力からすべての末尾の改行を削除し、foo正確echoに1つだけを追加することです(そしてバックスラッシュを処理できますが、そうではないと仮定します)。通常、出力は正確に1になる可能性が高いため、何も変わりません。

しかし、出力にfoo最後の改行文字がない場合は、echo意味とコマンドの置換を組み合わせて、パイプの右側に正しいテキストファイルを入力にインポートさせることで問題を解決できます。これは原則として重要です。技術的には、POSIX標準では入力が正しいテキストファイルである必要があり、そうでないと予期しない動作が発生する可能性があるためです。

grep実際、これらの実装では技術的に無効な入力が原因で問題が発生したり、改行のない最終行セグメントを他の行とは異なる方法で処理したことを見たことはありません。 grepの仕組みを考えると、基本的に改行を無視し、明確ではない動作が簡単に発生する可能性があります。 (また、fgets()行を読み取るためのC標準関数は、終了ステータスが改行が表示されてreadいるかどうかに依存するシェルとは異なり、最後に改行があるかどうかを実際に気にしません。 it it 読んでいる内容は最後に改行がなければならないと仮定し、無条件に最後の文字を削除しbuf[strlen(buf) - 1] = '\0'ます。

つまり、私はそれが実際に彼らが奇妙に見えるコマンドを実行した理由だとは信じていません。 (そして私はそれが間違った結果を生むとは思わないでしょうsystemctl。)おそらく彼らは自分がしていることについて実際には考えていません。

関連情報