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

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

使っています

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
    

答え2

私は最終的に以下を使用しました。

if [ -f ~/.rvm/scripts/rvm ]; then
  . ~/.rvm/scripts/rvm
else
  echo
  echo --- FAIL ---
  echo
  echo "You do not have a standard RVM install, cannot procede"
  echo "Please install rvm locally and re-run this program"
  exit 1
fi
repos="repo_3_ruby_191 repo_1_ruby_193 repo_2_ruby_211"
for repo in $repos
do
  if [ ! -f ~/zipcar/$repo/.ruby-version ]; then
    echo
    echo --- WARN ----
    echo
    echo No .ruby-version file present for $repo
    echo This *might* be an issue if there are ruby, e.g. rspec, tests.
    echo If so, please add and commit a .ruby-version file to $repo
    echo
  else
    version=$(cat ~/zipcar/$repo/.ruby-version)
    echo Checking ruby version: $version for repository: $repo"..."
    cd ~/zipcar/$repo 2>rvm_check.txt.$$
    if grep -qi 'not installed' ../rvm_check.txt.$$; then
      echo
      echo --- FAIL ---
      echo
      echo The required ruby version for $repo was not present on this machine
      echo Please install it with
      echo
      echo "  "RVM install $version
      echo
      echo and then re-run this program
      echo
      exit 1
    else
      echo $version Installed
    fi  
  fi  
done
echo
echo All required ruby versions verified as present through RVM

関連情報