[[または[を使用すると、"if pgrep"は機能しなくなります。

[[または[を使用すると、

goland.shprocess()が実行されているかどうかを検出しようとしています。私はこれを使用しました:

#!/bin/bash

if pgrep "goland.sh" >/dev/null 2>&1 ; then
    echo "running"
    exit 1
fi

echo "not running"

これはうまくいきますが、2つを理解していません。

  1. 使用するとうまくいかないのはなぜですか?if [[ pgrep "goland.sh" >/dev/null 2>&1 ]] ; then(プロセスが実行されていない場合でも常に「実行中」を印刷します。)
  2. 使用するとうまくいかないのはなぜですか?if [ pgrep "goland.sh" >/dev/null 2>&1 ] ; then(プロセスが実行されていない場合でも常に「実行中」を印刷します。)

私は1が構文解析方法に関連していると思います>が、2については完全に手がかりがありません。

ベストアンサー1

シェルのテスト構成[ ... ](または[[ ... ]]Bashの場合)がどのように機能するかについて誤解があるようです。

  • このifステートメントは、次のコマンドが0「エラーなし」を意味し、「true」と解釈される終了ステータスを返すことを確認します。その場合、実行はthenスクリプトの分岐に切り替わります(参照:バッシュマニュアル例えば)。
  • パターンに一致するプロセスが見つかると、pgrepコマンドは "true"を返します。そのため、インスタンスがアクティブな場合にのみこれを取得できます0runninggoland.sh
  • これは[、ファイル、文字列、および数値のテストを実行できる特別なコマンド(通常はシェル組み込み)で、開いている括弧と閉じた括弧の間の条件がtrueの場合は「true」を返します。ただし、特定の構文に応じて、1 つ以上のオペランドの操作が真であることを確認するように設計されています。たとえば、ある数字(演算子1)が別の数字(演算子2)より大きいかどうか(演算子)。たとえば、シェル変数nの値がと仮定すると、5テストは
    [ "$n" -gt 5 ]
    
    trueを返し、ステートメントのテストコマンドとして使用されると、実行はブランチに切り替わりifます。then
  • たとえば、文字列が空であるか、ファイルが存在するか、および/または実行可能であるかを確認できるように、いくつかのテスト構造が定義されています。ただし、すべてのケースで[ ... ]期待される結果を得るには、途中のコードの正しい構文を理解する必要があります。

これで、テスト構成括弧内に「raw」シェルコマンドが含まれます。これは状況によって多少異なりますが、有効な演算子なしで角括弧の間に複数の(定数)文字列トークンがあるため、構文エラーが発生します。

  • 使用すると、[[ ... ]]Bash 構文要素であり、Bash が間違った構文を認識するため、すぐに構文エラーが発生します。
  • ただし、これが発生すると、[ ... ]コマンドは自動的[に失敗します。注文する(通常は組み込まれていますが)引数が事前定義された演算子に対して意味があると予想し、最後の引数が最後の引数になると予想します]。ただし、エラー出力にリダイレクトしたため、/dev/nullエラーメッセージは失われます。 。
  • runningどちらの場合も、常に間違った構文で表示される出力を再現することはできません。

要約すると、テストに使用するプログラムは、実行中のプロセスが見つかった場合はすでに「true」を返すので[ ... ](または)構文を使用する必要はありません。[[ ... ]]テストに基づいてしたい場合出力pgrep「コマンドの置き換え」を使用する必要があります$(pgrep ...)(もちろん、出力リダイレクトも削除/dev/null)。

シェルスクリプトを確認することをお勧めしますshellcheck構文(およびいくつかの論理)エラーを防ぐために、多くのLinuxディストリビューションでスタンドアロンプ​​ログラムとしても使用できます。

おすすめ記事