Erro com if [-n $ diffCurr]: muitos argumentos

4

Eu tenho usado o código abaixo ok por algum tempo, mas agora recebo um erro

java Editor < "input/editor$i.in" > "tmp/editor$i.out"
diffCurr="$(diff "tmp/editor$i.out" "output/editor$i.out")"
if [ -n $diffCurr ]

Erro (ocorre na última linha do snippet acima):

[: too many arguments

O que há de errado? Eu estou tentando testar que o resultado do diff estava vazio (ou seja, mesmo conteúdo no arquivo)

    
por Jiew Meng 09.10.2011 / 12:01

4 respostas

13

Não é necessário colocar a saída de diff em uma variável, pois você pode dizer se os arquivos são diferentes com base no status de saída de diff , por exemplo,

if diff -q file1 file2 >/dev/null 2>&1; then
        # files are equal
else
        # files differ, or an error occurred
fi

diff retorna sucesso ( 0 ) se os arquivos não forem diferentes. Ajuste a lógica conforme necessário.

Testar o status de saída de comandos quando possível é quase sempre preferível à verificação ou análise de saída via substituição de comando.

Por questão de integridade, o erro com o seu exemplo original aconteceu porque você não citou "$diffCurr" na linha if , então passou por "divisão de palavras" em mais de uma palavra --- daí " muitos argumentos ".

    
por 09.10.2011 / 12:28
10

jw013 está certo, você não precisa dessa linha de qualquer maneira.

Mas, para responder à pergunta atual, você deixou aspas em torno da variável que passou para test (também conhecido como [ ).

Isto significa que se sua variável estiver vazia, será como se você não tivesse argumentos (por exemplo, [ -n ] ), e se sua variável contivesse espaços, seria como se você tivesse passado vários argumentos (eu suponho que isto é o que aconteceu).

Sempre envolva as strings em test entre aspas, por exemplo:

if [ -n "$myvar" ]
    
por 09.10.2011 / 15:23
1

Pode ser melhor testar o código de saída do comando diff do que a saída.

diffCurr="$(diff "tmp/editor$i.out" "output/editor$i.out")"
if [ $? -ne 0 ]; then  # different
...

Se você não está interessado na saída, então você pode fazer o que jw013 sugere.

    
por 09.10.2011 / 16:48
1

Além das boas respostas acima: Minha relação de amor / ódio com o bash é focada principalmente em sua força na substituição de parâmetros e no fato de que parar de substituir quando você quer pode ser um grande desafio - especialmente quando um variável é usada ou alterada mais de uma vez.

Como resultado, quase sempre codifico referências de variáveis como:

A="${B}"

Isso garante que B seja tratado como uma única string (na maioria das vezes o que eu quero) e permite que coisas como

A="${B}foo"

para funcionar, bem como várias outras opções sofisticadas que funcionam apenas dentro das chaves.

Se eu codificar até mesmo uma referência simples de variável segura como

A="${B}"

para começar, estou muito mais seguro quando volto para modificar o código mais tarde e possivelmente faço algo que pode falhar se aspas ou chaves estiverem faltando.

    
por 14.10.2011 / 23:27

Tags