O problema é o comando que você está usando para fazer o diff
. Toda vez que o comando executar os resultados, se houver uma diferença ou não, será acionado o comando mail
.
Exemplo
Aqui vamos simular os 2 arquivos usando 2 echo
de comandos como:
$ diff <(echo 1) <(echo 2)
1c1
< 1
---
> 2
Isso parece OK, mas o que acontece quando os comandos echo
são a mesma coisa?
$ diff <(echo 1) <(echo 1)
$
OK, isso não parece ser um problema, ou é? E se nós enviarmos a saída do comando diff
para dizer outro comando echo
:
$ diff <(echo 1) <(echo 1) | echo "hi"
hi
Veja que mesmo a saída vazia de diff
piped para outro comando ativará esse comando para execução.
Então, qual é o caminho certo?
O que você realmente quer fazer é uma das duas coisas. Verifique o status do comando diff
ou use um operador lógico como &&
(e) ou o operador ||
(ou operador).
Status
A maioria dos comandos, quando executados, retorna um status. Normalmente, um zero ou um para denotar que eles foram executados com sucesso ou falharam. Você pode ver o status de diff
analisando a variável de status $?
no Bash.
diff
retorna 0 se os arquivos corresponderem
$ diff <(echo 1) <(echo 1)
$ echo $?
0
diff
retorna um 1 se os arquivos não corresponderem
$ diff <(echo 1) <(echo 2)
1c1
< 1
---
> 2
$ echo $?
1
Então, por si só, parece útil, podemos dizer se um comando foi executado com sucesso ou não. No entanto, não temos como agir sobre isso. Então, vamos ver os operadores lógicos.
Operador lógico
O outro método é alterar 2 comandos para que, se o primeiro for bem-sucedido, o segundo seja executado. Por outro lado, você pode usar o operador alternativo para executar um segundo comando, se o primeiro falhar.
Exemplo
pragma diferente
$ diff <(echo 1) <(echo 2) || echo "they're different"
1c1
< 1
---
> 2
they're different
mesmo pragma
$ diff <(echo 1) <(echo 1) && echo "they're the same"
they're the same
OBSERVAÇÃO: Alguns cuidados devem ser usados se você usar esse método. Há um problema com o tipo de estrutura, porque os acima são verdadeiros operadores lógicos da mesma maneira que um if .. then .. else é. Você pode ler sobre isso no site de bashpitfalls .
Portanto, esta parece ser uma abordagem válida. Mas talvez haja outro caminho. Continue lendo.
Se então mais
Um terceiro método seria inscrever um bloco se / então para executar o programa mail
. Se / então os comandos estiverem relacionados aos operadores lógicos que mencionei há um minuto, eles são chamados de condicionais.
NOTA: Também diff
não é a melhor ferramenta para uso em declarações if / then. É melhor usar o comando cmp
, que pode retornar apenas um status e nada mais. Então, vamos atualizar isso agora também.
Exemplo
mesmo
$ cmp -s <(echo 1) <(echo 1)
$ echo $?
0
diferente
$ cmp -s <(echo 2) <(echo 1)
$ echo $?
1
Estender isso para um bloco se / então seria algo como isto:
$ if cmp -s <(echo 2) <(echo 1);then echo "same"; else echo "different";fi
different
$ if cmp -s <(echo 1) <(echo 1);then echo "same"; else echo "different";fi
same
Seu problema
Você poderia fazer algo assim para o seu problema original:
if cmp -s switchshow_reference switchshow_results; then
diff switchshow_reference switchshow_results \
| mail -s device_PORT_ERROR email_recipient
fi
UPDATE # 1
Ao analisar seu script atualizado, você precisa fazer as seguintes modificações:
ssh test@ip_of_device switchshow > switchshow_results
variable=$(diff switchshow_reference switchshow_results)
if [[ $variable -eq 0 ]]
then
echo $"nothing"
else
echo -n "$variable" | mail -s switch_HARDWARE_CHECK recipeint_email_address
fi
Os problemas que você estava enfrentando com a saída aparecendo como uma única linha foram causados pelo uso de echo
sem avisar para expandir caracteres especiais, como \n
. Por exemplo:
$ echo "oneline\ntwoline"
oneline\ntwoline
$ echo -e "oneline\ntwoline"
oneline
twoline
Uma outra modificação que fiz foi na forma como você executou o diff
. Isso não afetou sua funcionalidade de maneira ruim, mas os backticks ( \
.. ' ) has been deprecated in favor of this notation,
$ (...)'. Eles têm o benefício adicional de poder aninhar comandos dentro de outros comandos, como :
$ myvar=$(echo "good + $(echo bye)")
$ echo $myvar
good + bye