Las comillas evitan la "división de palabras". Es decir: desglosar las variables en varios elementos en los espacios en blanco (o para ser más exactos, en espacios, tabulaciones y líneas nuevas como se define en el valor de la $IFS
variable de shell predeterminada ).
Por ejemplo,
$ var="one two"
$ howmany(){ echo $#; }
$ howmany $var
2
$ howmany "$var"
1
Aquí definimos la howmany
función que simplemente nos permite saber cuántos parámetros posicionales se dan. Como puede ver, hay dos elementos que se pasan a la variable, y con las comillas, el texto en la variable se trata como una unidad.
Esto es importante para el paso preciso de la información. Por ejemplo, si la variable contiene la ruta al archivo y el nombre del archivo contiene espacios en cualquier parte de la ruta, el comando que está intentando ejecutar puede fallar o dar resultados inexactos. Si estuviéramos intentando crear un archivo con la $var
variable, touch $var
crearíamos dos archivos, pero touch "$var"
solo uno.
Lo mismo va para tu [ "$currentoutput" != "$lastoutput" ]
parte. Esta prueba particular realiza una comparación en dos cadenas. Cuando se ejecuta la prueba, el [
comando necesitaría ver 3 argumentos: una cadena de texto, el !=
operador y otra cadena de texto. Mantener comillas dobles evita la división de palabras, y el [
comando ve exactamente esos 3 argumentos. ¿Qué sucede si las variables no están entre comillas?
$ var="hello world"
$ foo="hi world"
$ [ $var != $foo ]
bash: [: too many arguments
$
Aquí, la división de palabras, y en su lugar [
ve a dos cadenas hello
y world
seguido por !=
, seguidas de otras dos cadenas hi world
. El punto clave es que sin comillas dobles, el contenido de las variables se entiende como unidades separadas en lugar de un elemento completo.
Asignar la sustitución de comandos no requiere comillas dobles como en
var=$( df )
donde tiene df
guardada la salida del comando var
. Sin embargo, es una buena costumbre siempre duplicar las variables de comillas y la sustitución de comandos a $(...)
menos que de hecho desee que la salida se trate como elementos separados.
En una nota al margen, el
while [ true ]
parte puede ser
while true
[
es un comando que evalúa sus argumentos y [ whatever ]
siempre es verdadero independientemente de lo que haya dentro. Por el contrario, while true
usa el comando true
que siempre devuelve el estado de salida de éxito (y eso es exactamente lo que while
necesita el bucle). La diferencia es un poco más de claridad y menos pruebas realizadas. Alternativamente, también podría usar en :
lugar detrue
Las comillas dobles en echo "" date and Time
parte probablemente podrían eliminarse. Simplemente insertan una cadena vacía y agregan espacio extra a la salida. Si eso es lo que desea, siéntase libre de mantenerlos allí, pero no hay un valor funcional particular en este caso.
lsusb >> test.log
Esta parte probablemente podría ser reemplazada por echo "$currentoutput" >> test.log
. No hay razón para lsusb
volver a ejecutar después de que ya se haya ejecutado currentoutput=$(lsusb)
. En los casos en que las nuevas líneas finales
deben conservarse en la salida, se podría ver el valor de ejecutar un comando varias veces, pero en caso de lsusb
que no sea necesario. Cuantos menos comandos externos llame, mejor, porque cada llamada a un comando no incorporado conlleva costos en CPU, uso de memoria y tiempo de ejecución (aunque los comandos probablemente estén precargados desde la memoria).
Ver también:
while [ true ]
produce un bucle infinito, pero tal vez no por la razón que cree que lo hace;while [ false ]
también produce un bucle infinito, porque con un solo argumento,[ ... ]
tiene éxito si ese argumento es una cadena no vacía.while true
en realidad ejecutará un comando llamadotrue
(que siempre tiene éxito).