我在用
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 使用该代码来决定是否转到then
或else
子句。 也设置了一个退出代码。因此这里 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