Estoy tratando de ver el número de archivos en mi /tmp/
directorio. Para esto pensé que este comando funcionaría:
watch sh -c 'ls /tmp/|wc -l'
Pero parece funcionar como si ls
no tuviera argumentos. A saber, estoy dentro ~
, y obtengo el número de archivos allí en lugar de /tmp/
. Encontré una solución, que parece funcionar:
watch sh -c 'ls\ /tmp/|wc -l'
Pero, ¿por qué necesito escapar del espacio entre ls
y /tmp/
? ¿Cómo se transforma el comando watch
para que la ls
salida se alimente wc
, pero /tmp/
no se pase como argumento ls
?
watch "sh -c 'ls /tmp | wc -l'"
hacer este comando debería obtener el efecto deseado. Esto no es culpa de los relojes, intentesh -c ls /tmp
y obtendrá su directorio de inicio (pero no tengo idea de por qué ...)watch
de forma incorrecta .El comando que se pasa awatch
su vez es alimentado porwatch
ash -c
, por lo que está haciendo en efectosh -c
dos veces./tmp
es un argumento parash
, en ese caso, no un argumento parals
.Respuestas:
La diferencia se puede ver a través de
strace
:En el caso de la comilla inversa,
ls /tmp
se pasa como un argumento único a-c
tosh
, que se ejecuta como se esperaba. Sin esta comilla inversa, el comando se divide en palabras cuando sewatch
ejecuta,sh
que a su vez ejecuta el suministradosh
, de modo que solols
se pasa como argumento a-c
, lo que significa que el sub-subsh
solo ejecutará unls
comando simple y enumera el contenido del trabajo actual directorio.Entonces, ¿por qué la complicación de
sh -c ...
? ¿Por qué no simplemente correrwatch 'ls /tmp|wc -l'
?fuente
strace
.ls /tmp
es ..." y "Sin esta comilla invertida , el comando es ...", y usabq
ynobq
como nombres de archivo, cuando todo se refiere a la barra invertida en suls\ /tmp
comando.Hay dos categorías principales de
watch
comandos (de los que se van a ejecutar comandos periódicamente,watch
no es un comando estándar, incluso hay sistemas en los quewatch
hace algo completamente diferente como espiar en otra línea tty en FreeBSD).Uno que ya pasa la concatenación de sus argumentos con espacios a un shell (en efecto llama
sh -c <concatenation-of-arguments>
) y otro que simplemente ejecuta el comando especificado con los argumentos especificados sin invocar un shell.Estás en la primera situación, así que solo necesitas:
Cuando tu lo hagas:
tu
watch
realmente corre:Y
sh -c ls /tmp/
ejecuta ells
script en línea donde$0
está/tmp/
(por lo quels
se ejecuta sin argumentos y enumera el directorio actual).Algunas de las
watch
implementaciones en la primera categoría (como la de procps-ng en Linux) aceptan una-x
opción para que se comporten como laswatch
de la segunda categoría. Entonces, allí, puedes hacer:fuente