Le virgolette impediscono la "divisione delle parole". Cioè: scomporre le variabili in più elementi in spazi bianchi (o, per essere più precisi, in spazi, tabulazioni e nuove righe come definito nel valore della $IFSvariabile shell predefinita ).
Per esempio,
$ var="one two"
$ howmany(){ echo $#; }
$ howmany $var
2
$ howmany "$var"
1
Qui definiamo la howmanyfunzione che ci fa semplicemente sapere quanti parametri posizionali sono dati. Come puoi vedere, ci sono due elementi che vengono passati alla variabile e con le virgolette il testo nella variabile viene trattato come una sola unità.
Questo è importante per il passaggio accurato di informazioni. Ad esempio, se la variabile contiene il percorso del file e il nome del file contiene spazi in qualsiasi punto del percorso, il comando che si sta tentando di eseguire potrebbe non riuscire o dare risultati imprecisi. Se stessimo provando a creare un file con la $varvariabile, touch $varcreeremmo due file, ma touch "$var"solo uno.
Lo stesso vale per la tua [ "$currentoutput" != "$lastoutput" ]parte. Questo particolare test esegue un confronto su due stringhe. Quando viene eseguito il test, il [comando dovrebbe visualizzare 3 argomenti: una stringa di testo, l' !=operatore e un'altra stringa di testo. Mantenere le virgolette doppie impedisce la divisione delle parole e il [comando visualizza esattamente questi 3 argomenti. Ora cosa succede se le variabili non sono quotate?
$ var="hello world"
$ foo="hi world"
$ [ $var != $foo ]
bash: [: too many arguments
$
Qui, si verifica la divisione delle parole e [vede invece due stringhe helloe worldseguite da !=, seguite da altre due stringhe hi world. Il punto chiave è che senza virgolette doppie, il contenuto delle variabili è inteso come unità separate anziché come un intero elemento.
L'assegnazione della sostituzione di comando non richiede virgolette doppie come in
var=$( df )
dove hai dfsalvato l'output del comando var. Tuttavia, è una buona abitudine raddoppiare sempre le variabili tra virgolette e sostituire i comandi a $(...)meno che non si desideri effettivamente che l'output sia trattato come elementi separati.
In una nota a margine, il
while [ true ]
parte può essere
while true
[è un comando che valuta i suoi argomenti ed [ whatever ]è sempre vero indipendentemente da ciò che è dentro. Al contrario, while trueutilizza il comando trueche restituisce sempre lo stato di uscita riuscita (ed è esattamente ciò di cui ha whilebisogno il ciclo). La differenza è un po 'più di chiarezza e meno test eseguiti. In alternativa, puoi anche usare :invece ditrue
Le doppie virgolette in echo "" date and Timeparte potrebbero essere probabilmente rimosse. Inseriscono semplicemente una stringa vuota e aggiungono ulteriore spazio all'output. Se lo desideri, sentiti libero di tenerli lì, ma in questo caso non c'è un valore funzionale particolare.
lsusb >> test.log
Questa parte potrebbe probabilmente essere sostituita con echo "$currentoutput" >> test.log. Non c'è motivo di correre di lsusbnuovo dopo che è già stato eseguito currentoutput=$(lsusb). Nei casi in cui le nuove righe finali
devono essere preservate nell'output, si potrebbe vedere il valore nell'esecuzione di un comando più volte, ma in questo caso lsusbnon è necessario. Meno comandi esterni vengono chiamati, meglio è, perché ogni chiamata a un comando non incorporato comporta costi in CPU, utilizzo della memoria e tempo di esecuzione (anche se i comandi sono probabilmente precaricati dalla memoria).
Guarda anche:
while [ true ]produce un ciclo infinito, ma forse non per il motivo che pensi che lo faccia; producewhile [ false ]anche un ciclo infinito, perché con un singolo argomento ha[ ... ]esito positivo se tale argomento è una stringa non vuota.while truesarà effettivamente eseguire un comando di nometrue(che riesce sempre).