Les guillemets empêchent la "division des mots". C'est-à-dire: décomposer les variables en plusieurs éléments au niveau des espaces (ou pour être plus exact, aux espaces, tabulations et sauts de ligne tels que définis dans la valeur de la $IFS
variable shell par défaut ).
Par exemple,
$ var="one two"
$ howmany(){ echo $#; }
$ howmany $var
2
$ howmany "$var"
1
Ici, nous définissons la howmany
fonction qui nous permet juste de savoir combien de paramètres de position sont donnés. Comme vous pouvez le voir, deux éléments sont passés à la variable et, avec les guillemets, le texte de la variable est traité comme une seule unité.
Ceci est important pour une transmission précise des informations. Par exemple, si la variable contient le chemin d'accès au fichier et que le nom de fichier contient des espaces n'importe où dans le chemin d'accès, la commande que vous essayez d'exécuter peut échouer ou donner des résultats inexacts. Si nous essayions de créer un fichier avec la $var
variable, touch $var
créerait deux fichiers, mais touch "$var"
un seul.
Il en va de même pour votre [ "$currentoutput" != "$lastoutput" ]
part. Ce test particulier effectue une comparaison sur deux chaînes. Lorsque le test s'exécute, la [
commande doit voir 3 arguments - une chaîne de texte, l' !=
opérateur et une autre chaîne de texte. Garder les guillemets doubles empêche le fractionnement des mots et la [
commande voit exactement ces 3 arguments. Maintenant, que se passe-t-il si les variables ne sont pas citées?
$ var="hello world"
$ foo="hi world"
$ [ $var != $foo ]
bash: [: too many arguments
$
Ici, le fractionnement de mot se produit et [
voit à la place deux chaînes hello
et world
suivi de !=
, suivi de deux autres chaînes hi world
. Le point clé est que, sans guillemets doubles, le contenu des variables est compris comme des unités distinctes plutôt que comme un élément entier.
L'attribution d'une substitution de commande ne nécessite pas de guillemets doubles comme dans
var=$( df )
où vous avez df
enregistré la sortie de la commande var
. Cependant, c'est une bonne habitude de toujours doubler les variables entre guillemets et la substitution de commandes, $(...)
sauf si vous voulez en fait que la sortie soit traitée comme des éléments distincts.
En passant, le
while [ true ]
une partie peut être
while true
[
est une commande qui évalue ses arguments et [ whatever ]
est toujours vraie indépendamment de ce qu'il y a à l'intérieur. En revanche, while true
utilise la commande true
qui renvoie toujours le statut de sortie de réussite (et c'est exactement ce dont la while
boucle a besoin). La différence est un peu plus de clarté et moins de tests effectués. Alternativement, vous pouvez également utiliser :
au lieu detrue
Les doubles guillemets echo "" date and Time
pourraient en partie être supprimés. Ils insèrent simplement une chaîne vide et ajoutent un espace supplémentaire à la sortie. Si vous le souhaitez, n'hésitez pas à les conserver, mais il n'y a pas de valeur fonctionnelle particulière dans ce cas.
lsusb >> test.log
Cette partie pourrait probablement être remplacée par echo "$currentoutput" >> test.log
. Il n'y a aucune raison de lsusb
recommencer après qu'il ait déjà été exécuté currentoutput=$(lsusb)
. Dans les cas où les retours à la ligne
doivent être conservés dans la sortie - on peut voir la valeur de l'exécution d'une commande plusieurs fois, mais dans le cas contraire, lsusb
cela n'est pas nécessaire. Moins vous appelez de commandes externes, mieux c'est, car chaque appel à une commande non intégrée entraîne des coûts de CPU, d'utilisation de la mémoire et de temps d'exécution (même si les commandes sont probablement préchargées depuis la mémoire).
Voir également:
while [ true ]
cela produit une boucle infinie, mais peut-être pas pour la raison pour laquelle vous pensez que c'est le cas; produitwhile [ false ]
également une boucle infinie, car avec un seul argument,[ ... ]
réussit si cet argument est une chaîne non vide. exécutera enwhile true
fait une commande nommée (qui réussit toujours).true