Shell
如何測試具有值的文件?
我在用
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
我得到了我想要的是/否,但如何避免
[:
錯誤?
代替:
if [ -z `cat rvm_check.txt | grep not` ]
和:
if ! grep -q not rvm_check.txt
test
在語句中使用的原因if
是因為它設置了一個退出程式碼,shell 使用該程式碼來決定轉到then
orelse
子句。grep
還設置退出程式碼。因此,這裡不需要測試 ,[
。grep
如果找到字元串,則將退出程式碼設置為成功 (0)。如果找不到字元串,您希望成功。因此,我們通過使用來否定退出程式碼結果!
。解釋
測試命令 ,
[
期望後面跟著一個字元串-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