数日前からBashを学び始めました。
grep
式の終了状態を次の変数にインポートしようとしています。
check=grep -ci 'text' file.sh
私が得た結果は次のとおりです。
No command '-ic' found
これを行うには、パイプコマンドを使用する必要がありますか?
答え1
注文、
check=grep -ci 'text' file.sh
-ci
シェルは、「引数をtext
使用してコマンドを実行しfile.sh
、変数をcheck
環境の値に設定します」と解釈します。grep
シェルは、最後に実行されたコマンドの終了値を変数に保存します?
。次のように、独自の変数のいずれかに対応する値を割り当てることができます。
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
。ここで一致した項目には実際に興味がありません。)
または、パターンが現れたときに「仕事をする」ことを望む場合いいえ確立された:
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
。
答え2
check=grep
コマンドに渡された環境で変数を設定するようにbashに指示しました。
-ci 'text' file.sh
しかし、ci
それは存在しません。
コマンドをバックティックやドル記号の前に括弧で囲むという意味だと思います。どちらも「テキスト」を含むファイルの行数を割り当てます(大文字と小文字を区別しません)。
check=`grep -ci 'text' file.sh`
check=$(grep -ci 'text' file.sh)
$check
一致するものがない場合は0になり、一致するものがあれば正になります。
答え3
あなたの質問は明確ではありませんが、送信したコードによると、変数がコマンドの終了ステータスをcheck
保存したいようです。grep
これを行う方法は実行することです。
grep -ci 'text' file.sh
check=$?
シェルからコマンドを実行すると、特別なシェルパラメータを使用してコマンドの終了ステータスを取得できます$?
。
POSIX(Unixシリーズオペレーティングシステムの標準)はそれを文書に記録します。シェル仕様Bash の実装は次の文書で文書化されています。特殊パラメータ。
あなたは新しい学習者なので、基礎を学ぶために良い本やオンラインチュートリアルで始めることをお勧めします。 Stack Exchange Webサイトでは外部リソースの推奨を推奨していませんが、LhunathとGreyCatのBashガイド。
答え4
他の答えは、コマンドが機能しない理由と結果をテストする方法に関する良い提案を明らかにします。もう一つの点を追加したい。
$(コマンド)$?終了コードを追加
コマンド置換と終了コードチェックの両方を1行にまとめてこれを行うことができます。終了コードを出力に数値として追加します。
check=$( grep -ci 'text' file.sh )$?
これは実際には$(some command)
(コマンドの文字列出力のインポート)の後に$?
(最後のコマンドの終了コードのインポート)が続きます。作業するには、スペースなしで一緒に使用する必要があります。
出力可能性がある場合(ほとんどのコマンドの場合)、これを抑制する方法を使用する必要があります> /dev/null 2>&1
。
などのテストコマンドを使用している場合は、この作業は不要ですtest -d <directory>
。
check=$( grep -ci 'text' file.sh > /dev/null 2>&1)$?
関数を使用して抽象化できます。
e() {
$@ > /dev/null 2>&1
}
# Usage:
check=$(e grep -ci 'text' file.sh)$?
テスト終了コード
後で使用するには、0をテストしてください(成功的に)。
[ $check -eq 0 ] && echo "passed" || echo "didn't pass"
[ $check -ne 0 ] && echo "didn't pass" || echo "passed"
if/then/else 構文を使用して 0 に対してテスト (成功):
if [ $check -eq 0 ]; then
echo "passed"
else
echo "didn't pass"
fi
if [ $check -ne 0 ]; then
echo "didn't pass"
else
echo "passed"
fi
終了コードを直接テスト
サブシェルで使用すると、exit
直接使用できる数値に基づいて正しい終了コードが生成されます。(
)
(exit $check) && echo "check passed" || echo "check didn't pass"
! (exit $check) && echo "check didn't pass" || echo "check passed"
if/then/else 構造を使用し、終了コードを直接使用します。
if (exit $check); then
echo "passed"
else
echo "didn't pass"
fi
if ! (exit $check); then
echo "didn't pass"
else
echo "passed"
fi
return
代わりに、exit
zsh(bashではない)を含む一部のシェルでも機能します。
かっこいい
さらに簡単にするには、次の機能を使用します。
t() { return $1; }
これで、次のようにテストできます。
t $check && echo "passed" || echo "didn't pass"
! t $check && echo "didn't pass" || echo "passed"