As aspas impedem a "divisão de palavras". Ou seja: dividir variáveis em vários itens em caracteres de espaço em branco (ou, para ser mais exato, em espaços, guias e novas linhas, conforme definido no valor da $IFSvariável de shell padrão ).
Por exemplo,
$ var="one two"
$ howmany(){ echo $#; }
$ howmany $var
2
$ howmany "$var"
1
Aqui, definimos a howmanyfunção que nos permite saber quantos parâmetros posicionais são dados. Como você pode ver, há dois itens sendo passados para a variável e, com as aspas, o texto na variável é tratado como uma unidade.
Isso é importante para a passagem precisa de informações. Por exemplo, se a variável contiver o caminho para o arquivo e o nome do arquivo contiver espaços em qualquer lugar do caminho, o comando que você está tentando executar poderá falhar ou fornecer resultados imprecisos. Se tentássemos criar um arquivo com a $varvariável, touch $varcriaríamos dois arquivos, mas touch "$var"apenas um.
O mesmo vale para sua [ "$currentoutput" != "$lastoutput" ]parte. Este teste específico realiza uma comparação em duas seqüências de caracteres. Quando o teste é executado, o [comando precisa ver três argumentos - uma sequência de texto, o !=operador e outra sequência de texto. Manter aspas duplas evita a divisão de palavras, e o [comando vê exatamente esses 3 argumentos. Agora, o que acontece se as variáveis não estiverem entre aspas?
$ var="hello world"
$ foo="hi world"
$ [ $var != $foo ]
bash: [: too many arguments
$
Aqui, a divisão da palavra ocorre e, em vez disso, ele [vê duas cadeias helloe é worldseguido por !=, seguido por duas outras cadeias hi world. O ponto principal é que, sem aspas duplas, o conteúdo das variáveis é entendido como unidades separadas, em vez de um item inteiro.
Atribuir substituição de comando não requer aspas duplas, como em
var=$( df )
onde você tem a dfsaída do comando salva var. No entanto, é um bom hábito sempre colocar aspas variáveis e substituir comandos, a $(...)menos que você realmente queira que a saída seja tratada como itens separados.
Em uma nota lateral, o
while [ true ]
parte pode ser
while true
[é um comando que avalia seus argumentos e [ whatever ]sempre é verdadeiro, independentemente do que está dentro. Por outro lado, while trueusa o comando trueque sempre retorna o status de saída com êxito (e é exatamente isso que o whileloop precisa). A diferença é um pouco mais de clareza e menos testes realizados. Como alternativa, você também pode usar em :vez detrue
As aspas duplas em echo "" date and Timeparte provavelmente poderiam ser removidas. Eles apenas inserem uma string vazia e adicionam espaço extra à saída. Se isso for desejado, fique à vontade para mantê-los lá, mas não há um valor funcional específico nesse caso.
lsusb >> test.log
Esta parte provavelmente poderia ser substituída por echo "$currentoutput" >> test.log. Não há razão para executar lsusbnovamente depois de já ter sido executado currentoutput=$(lsusb). Nos casos em que novas linhas finais
precisam ser preservadas na saída - é possível ver o valor em executar um comando várias vezes, mas no caso de lsusbnão haver necessidade disso. Quanto menos comandos externos você chamar, melhor, porque todas as chamadas para um comando não interno incorrem em custos de CPU, uso de memória e tempo de execução (mesmo que os comandos sejam provavelmente pré-carregados da memória).
Veja também:
while [ true ]produz um loop infinito, mas talvez não pelo motivo que você pensa;while [ false ]também produz um loop infinito, porque com um único argumento[ ... ]é bem-sucedido se esse argumento for uma sequência não vazia.while truena verdade, executará um comando chamadotrue(que sempre é bem-sucedido).