如何测试文件是否具有值?

如何测试文件是否具有值?

我在用

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在语句中使用 的原因if是它设置了一个退出代码,shell 使用该代码来决定是否转到thenelse子句。 也设置了一个退出代码。因此这里 grep不需要测试。如果找到字符串,则将退出代码设置为成功 (0)。如果未找到字符串,则希望成功。因此,我们使用 来否定退出代码结果。[grep!

解释

测试命令[期望后面跟着一个字符串-z。如果 grep 命令生成多个单词,则测试将失败并出现您看到的错误。

作为示例,请考虑以下示例文件:

$ cat rvm_check.txt
one not two

的输出grep看起来像:

$ cat rvm_check.txt | grep not
one not two

test执行时,所有三个单词都会出现在[...]导致命令失败的内部:

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

这与您输入的内容相同:

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

一种解决方案是使用双引号:

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

双引号会阻止 shell 执行分词。因此,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

相关内容