ファイルに値があるかどうかをテストする方法は?

ファイルに値があるかどうかをテストする方法は?

使っています

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)に設定されます。文字列が見つからない場合、成功すると予想されます。したがって、終了コードの結果を無効にするために使用します。thenelsegrep[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
    

おすすめ記事