Substituir:
if [ -z 'cat rvm_check.txt | grep not' ]
Com:
if ! grep -q not rvm_check.txt
O motivo para usar test
em uma instrução if
é porque ela define um código de saída que o shell usa para decidir ir para a cláusula then
ou else
. grep
também define um código de saída. Consequentemente, não há necessidade de teste, [
, aqui. grep
define o código de saída para sucesso (0), se encontrou a cadeia. Você quer sucesso se a string não for encontrada. Assim, negamos o resultado do código de saída usando !
.
Explicação
O comando de teste, [
, espera que uma única sequência siga -z
. Se o comando grep produzir mais de uma palavra, o teste falhará com o erro que você viu.
Como exemplo, considere este arquivo de amostra:
$ cat rvm_check.txt
one not two
A saída de grep
se parece com:
$ cat rvm_check.txt | grep not
one not two
Quando test
é executado, todas as três palavras aparecem dentro do [...]
, fazendo com que o comando falhe:
$ [ -z 'cat rvm_check.txt | grep not' ]
bash: [: too many arguments
Isto é o mesmo que se você tivesse digitado:
$ [ -z one not two ]
bash: [: too many arguments
Uma solução para isso é usar aspas duplas:
$ [ -z "'cat rvm_check.txt | grep not'" ]
As aspas duplas impedem que o shell execute divisão de palavras . Como resultado, a saída de grep
aqui é tratada como uma única string, não dividida em palavras separadas.
No entanto, como grep
define um código de saída sensato, não há necessidade de teste, conforme mostrado na linha recomendada acima.
Comentários adicionais
-
O formulário atualmente preferido para substituição de comando é
$(...)
. Enquanto os backticks ainda funcionam, eles são frágeis. Em particular, os backticks não podem ser aninhados. -
Nos comandos que usam nomes de arquivos no comando, o uso de
cat
é desnecessário. Em vez de:cat somefile | grep something
Use apenas:
grep something somefile