如何测试具有值的文件?

Mic*_*ant 2 shell ruby rvm

我在用

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
Run Code Online (Sandbox Code Playgroud)

它主要工作,但我得到:

$ ./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
$
Run Code Online (Sandbox Code Playgroud)

无论我尝试-s还是-z

我得到了我想要的 YES/NO 但如何避免[:错误?

Joh*_*024 5

代替:

if [ -z `cat rvm_check.txt | grep not` ]
Run Code Online (Sandbox Code Playgroud)

和:

if ! grep -q not rvm_check.txt
Run Code Online (Sandbox Code Playgroud)

testif语句中使用的原因是因为它设置了一个退出代码,shell 用它来决定转到thenorelse子句。 grep还设置退出代码。因此[,这里不需要测试,。 grep如果找到字符串,则将退出代码设置为成功 (0)。如果找不到字符串,您希望成功。因此,我们使用 否定退出代码结果!

解释

测试命令[需要一个字符串跟随-z。如果 grep 命令产生多个单词,则测试将失败并显示您看到的错误。

例如,请考虑以下示例文件:

$ cat rvm_check.txt
one not two
Run Code Online (Sandbox Code Playgroud)

的输出grep看起来像:

$ cat rvm_check.txt | grep not
one not two
Run Code Online (Sandbox Code Playgroud)

test执行这三个词出现内部[...]引起命令失败:

$ [ -z `cat rvm_check.txt | grep not` ]
bash: [: too many arguments
Run Code Online (Sandbox Code Playgroud)

这与您输入的情况相同:

$ [ -z one not two ]
bash: [: too many arguments
Run Code Online (Sandbox Code Playgroud)

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

$ [ -z "`cat rvm_check.txt | grep not`" ]
Run Code Online (Sandbox Code Playgroud)

双引号可防止 shell 执行分。因此,grep此处的输出被视为单个字符串,而不是拆分为单独的单词。

但是,由于grep设置了合理的退出代码,因此如上面推荐的行所示,不需要测试。

补充评论