2

I am using

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

and it's mostly working but I get:

$ ./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
$

whether I try -s or -z

I am getting the YES/NO that I want but how to avoid the [: error?

5

Replace:

if [ -z `cat rvm_check.txt | grep not` ]

With:

if ! grep -q not rvm_check.txt

The reason to use test in an if statement is because it sets an exit code that the shell uses to decide to go to the then or else clause. grep also sets an exit code. Consequently there is no need for test, [, here. grep sets the exit code to success (0), if it found the string. You want success to be if the string is not found. Thus, we negate the exit code result by using !.

Explanation

The test command, [, expects a single string to follow -z. If the grep command produces more than one word, then the test will fail with the error that you saw.

As an example, consider this sample file:

$ cat rvm_check.txt
one not two

The output of grep looks like:

$ cat rvm_check.txt | grep not
one not two

When test is executed all three words appear inside the [...] causing the command to fail:

$ [ -z `cat rvm_check.txt | grep not` ]
bash: [: too many arguments

This is just the same as if you had entered:

$ [ -z one not two ]
bash: [: too many arguments

One solution for that is to use double-quotes:

$ [ -z "`cat rvm_check.txt | grep not`" ]

Double-quotes prevent the shell from performing word splitting. As a result, the output from grep here is treated as a single string, not split into separate words.

However, since grep sets a sensible exit code, there is, as shown in the recommended line above, no need for test.

Additional comments

  • The currently preferred form for command substitution is $(...). While backticks still work, they are fragile. In particular, backticks cannot be nested.

  • On commands that take filenames on the command, the use of cat is unnecessary. Instead of:

    cat somefile | grep something
    

    Just use:

    grep something somefile
    
0

I ended up using:

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
  • 'preciate the edit for brevity but also using it for notes for a couple of days if possible – Michael Durrant Nov 23 '14 at 3:23
  • What does that mean? You have a copy locally, this should be an answer (ie., the relevant section); as it is it is buried in lines of completely irrelevant echos... – jasonwryan Nov 23 '14 at 4:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.