web-dev-qa-db-ja.com

コマンドの終了ステータスを変数に抽出するにはどうすればよいですか?

私は数日前にバッシュを学び始めました。

私はgrep式の終了ステータスを次のような変数に取得しようとしています:

check=grep -ci 'text' file.sh

そして私が得た出力は

No command '-ic' found

パイプコマンドで実行する必要がありますか?

15
omri gilhar

あなたの命令、

check=grep -ci 'text' file.sh

シェルによって「引数textおよび-ciを指定してコマンドfile.shを実行し、変数checkをその環境で値grepに設定する」とシェルによって解釈されます。


シェルは、最後に実行されたコマンドの終了値を変数?に格納します。次のように、その値を独自の変数の1つに割り当てることができます。

grep -i 'PATTERN' file
check=$?

この値を使用する場合は、check変数を使用できます。

if [ "$check" -eq 0 ]; then
    # do things for success
else
    # do other things for failure
fi

または、別の変数の使用をスキップして、$?をすべて一緒に検査する必要があります。

if grep -q -i 'pattern' file; then
  # do things (pattern was found)
else
  # do other things (pattern was not found)
fi

-qに注意してください。これは、grepに何も出力せず、何かが一致するとすぐに終了するように指示します。ここで何が一致するかにはあまり興味がありません)

または、パターンがnotであるときに「何かをしたい」だけの場合:

if ! grep -q -i 'pattern' file; then
  # do things (pattern was not found)
fi

$?を別の変数に保存する必要があるのは、次のように$?の値が上書きされたときに、後で使用する必要がある場合のみです。

mkdir "$dir"
err=$?

if [ "$err" -ne 0 ] && [ ! -d "$dir" ]; then
    printf 'Error creating %s (error code %d)\n' "$dir" "$err" >&2
    exit "$err"
fi

上記のコードスニペットでは、$?は、[ "$err" -ne 0 ] && [ ! -d "$dir" ]テストの結果によって上書きされます。ここに保存する必要があるのは、実際に表示してexitで使用する場合のみです。

27
Kusalananda

コマンドに渡す環境で変数check=grepを設定するようにbashに指示した

-ci 'text' file.sh

しかし、ciは存在しません。

私はあなたがそのコマンドをバックティック、またはドル記号が前に付いた括弧で囲むことを意図していたと信じています。

check=`grep -ci 'text' file.sh`

check=$(grep -ci 'text' file.sh)

ここで、$checkは、一致しない場合は0、一致する場合は正の値になります。

4
Monty Harder

あなたの質問は不明瞭ですが、あなたが提出したコードに基づいて、変数checkgrepコマンドの終了ステータスを保存したいようです。これを行う方法は実行することです

grep -ci 'text' file.sh
check=$?

シェルからコマンドを実行すると、その終了ステータスは特別なシェルパラメータ$?

これは、POSIX(Unixライクなオペレーティングシステムの標準)の シェルの仕様 で文書化されており、Bashの実装は 特別なパラメーター で文書化されています。

あなたは新しい学習者なので、基本を理解するには、優れた本やオンラインチュートリアルから始めることを強くお勧めします。 Stack Exchangeサイトでは外部リソースの推奨は推奨されていませんが、 LhunathおよびGreyCatのBashガイド をお勧めします。

4

出力を確認するときに-cを使用する理由が混乱していますか?これは、何かが一致した回数をチェックするために使用されます-成功したかどうかではありません。

   -c, --count
          Suppress normal output; instead print a count of matching  lines
          for  each  input  file.  With the -v, --invert-match option (see
          below), count non-matching lines.  (-c is specified by POSIX.)

この例では

check="$(grep --silent -i 'text' file.sh; echo $?)"

終了コードを除いて何も出力しません。終了コードはエコーされます。これは、変数チェックが使用する出力です。単一行なので、私もそれを好みます。

--silentを-qに置き換えることができます。うまくいったかどうかにかかわらず、grepの出力には興味がないので、これを使用します。

   -q, --quiet, --silent
          Quiet;  do  not  write  anything  to  standard   output.    Exit
          immediately  with  zero status if any match is found, even if an
          error was detected.  Also see the -s  or  --no-messages  option.
          (-q is specified by POSIX.)

$ check=$(echo test | grep -qi test; echo $?) # check variable is now set
$ echo $check
0
$ check=$(echo null | grep -qi test; echo $?)
$ echo $check
1
1
Miati

Grepコマンドの出力を変数に割り当てる正しい方法は、@ monty-harderが言及したとおりです。

check=`grep -ci 'text' file.sh`
check=$(grep -ci 'text' file.sh)

ただし、このコマンドの終了ステータスを変数に割り当てるには、次のようにコマンドを実行した直後にシェルパラメータ$?を使用する必要があります。

grep -ci 'text' file.sh
check=$?
echo $check
1
Curious