使っています
source ~/.rvm/scripts/rvm
repos="repo_1_ruby_193 repo_2_ruby_211 repo_3_ruby_191"
> rvm_check.txt
for repo in $repos
do
cd ~/zipcar/$repo 2>rvm_check.txt
cd ..
echo $repo
if [ -z `cat rvm_check.txt | grep not` ] # line 9
then
echo "YES"
else
echo "NO"
exit 1
fi
done
ほとんどはうまくいきますが、次のような結果が得られます。
$ ./multi_repo_rubies.sh
repo_1_ruby_193
YES
repo_2_ruby_211
YES
repo_3_ruby_191
./multi_repo_rubies.sh: line 9: [: too many arguments
NO
$
私が-s
何をしようとしても-z
希望の「はい/いいえ」が表示されます。しかし、その[:
エラーを防ぐにはどうすればよいですか?
ベストアンサー1
変える:
if [ -z `cat rvm_check.txt | grep not` ]
そして:
if ! grep -q not rvm_check.txt
test
ステートメントで使用する理由は、シェルがOR句にif
移動するかどうかを決定するために使用する終了コードを設定するためです。終了コードも設定されています。したがって、ここではテストは必要ありません。文字列が見つかると、終了コードは成功(0)に設定されます。文字列が見つからない場合、成功すると予想されます。したがって、終了コードの結果を無効にするために使用します。then
else
grep
[
grep
!
説明する
テストコマンドは[
文字列が続くと予想されます-z
。 grep コマンドが 2 つ以上の単語を生成すると、表示されるエラーとともにテストが失敗します。
たとえば、次のサンプルファイルを考えてみましょう。
$ cat rvm_check.txt
one not two
出力はgrep
次のとおりです。
$ cat rvm_check.txt | grep not
one not two
test
実行すると、3つの単語がすべて[...]
内部に表示され、コマンドが失敗します。
$ [ -z `cat rvm_check.txt | grep not` ]
bash: [: too many arguments
これは入力した内容と同じです。
$ [ -z one not two ]
bash: [: too many arguments
1つの解決策は二重引用符を使用することです。
$ [ -z "`cat rvm_check.txt | grep not`" ]
二重引用符はシェルの実行を防ぎます。噴射。したがって、grep
ここの出力は別の単語に分割されず、単一の文字列として扱われます。
ただし、grep
合理的な終了コードが設定されているため、上記の推奨行に示すようにテストは不要です。
追加コメント
現在好ましいコマンド代替形式はです
$(...)
。バックティックはまだ動作しますが脆弱です。特にバックティックは入れ子にすることはできません。cat
これは、コマンドでファイル名を使用するコマンドには必要ありません。変える:cat somefile | grep something
ちょうど使用:
grep something somefile