Estou tentando escrever uma declaração if composta usando o novo teste no Bash. Quero verificar se existe um arquivo e se dois outros arquivos têm conteúdos específicos. Minhas pesquisas grep parecem não funcionar tão bem quando aninhadas em um teste.
echo "a" >> file_a
echo "b" >> file_b
echo "c" >> file_c
if [[ -f file_a && \
$(grep -q "b" file_b) && \
$(grep -q "c" file_c) ]]; then
echo "Got 'em"
fi
Ao testar o status de saída de um comando (por exemplo
grep
, ), você não precisa ou deseja[[ ]]
ou$( )
nada disso.if
verifica o status de saída do que quer que esteja entreif
ethen
e toma a ramificação apropriada com base no êxito ou na falha.$( )
existe para capturar a saída de um comando (ou seja, o que ele imprime enquanto é executado -grep -q
não imprime nada) e usa-o como parte de outro comando. Isso não é o que você quer.[[ ]]
avalia uma expressão de teste (que pode testar, por exemplo, se existe um arquivo, se duas strings são iguais etc.) e converte o resultado em um status de saída. Mas comgrep -q
ele já está produzindo um status de saída, então você não precisa de algum tipo de teste para colocá-lo nesse formulário.Você precisa verificar se
[[ ]]
file_a existe, mas essa é a única função que ele desempenhará aqui. E você precisa&&
fazer um comando composto que seja bem-sucedido somente se todas as partes dele forem bem-sucedidas. Então o que você quer é:Você pode remover o
-q
from grep e testar se a expressão dentro da substituição de comando não está vazia usando o-n
sinalizador.Embora o
-n
possa ser omitido, o que funcionará como se você tivesse o-n
sinalizador dentro do teste.Geralmente, a
if
cláusula e o[[
ou[
não são necessários se você for apenas testar uma correspondência de padrão usando grep.Como alternativa, livre-se totalmente do "se":
grep
tem código de saída 0 em caso de sucesso, mastest
deseja um valor verdadeiro. Você tem que inverter o código de saída do grep ou verificar se saiu com 0:ou
Idealmente, há uma maneira mais legível do que colocá-lo em um subshell com
$()
.