Solo estoy saltando a Unix desde un mundo diferente, y quería saber si
while true
do
/someperlscript.pl
done
El script perl en sí tiene internamente una carpeta / observador de archivos que se ejecuta cuando los archivos se cambian en la ubicación de destino.
¿Es esta ( while true
) una buena idea? Si no, ¿cuál es un enfoque robusto preferido?
TIA
EDITAR: Dado que esto parece haber generado un poco de interés, aquí está el escenario completo. El script perl mismo mira un directorio usando un observador de archivos. Al recibir nuevos archivos (llegan a través de rsync), recoge el nuevo y lo procesa. Ahora los archivos entrantes pueden estar corruptos (no pregunte ... provenientes de una frambuesa pi), y a veces el proceso puede no ser capaz de manejarlo. No sé exactamente por qué, porque todavía no conocemos todos los escenarios.
PERO: si el proceso falla por algún motivo, queremos que esté en funcionamiento y que se ocupe del siguiente archivo, porque el siguiente archivo no tiene ninguna relación con el anterior que podría haber causado el error.
Por lo general, habría usado algún tipo de captura de todo y envuelto todo el código a su alrededor para que NUNCA se bloquee. Pero no estaba seguro de Perl.
Por lo que he entendido, usar algo como supervisión es un buen enfoque para esto.
inotify
API para evitar un bucle ocupado esperando que los archivos cambien en su directorio de destino.Respuestas:
Eso depende de qué tan rápido regrese el script perl. Si regresa rápidamente, es posible que desee insertar una pequeña pausa entre ejecuciones para evitar la carga de la CPU, por ejemplo:
Esto también evitará un problema de CPU si el script no se encuentra o se bloquea de inmediato.
El bucle también podría implementarse mejor en el script perl para evitar estos problemas.
Editar:
Como escribió, el único propósito del bucle es reiniciar el script perl en caso de que falle, un mejor enfoque sería implementarlo como un servicio monitoreado, pero la forma precisa de hacerlo depende del sistema operativo. Por ejemplo: Solaris smf, Linux systemd o un reiniciador basado en cron.
fuente
while sleep 1; do ...
para guardar la verdadera llamada.until ! sleep 1; do ...; done
aún guardará esa llamada incorporada al iniciar el script de inmediato.sleep 1& /someperlscript.pl; wait
.until
instrucción, la he confundido con undo/until
bucle hipotético que no existe en el shell.Las otras respuestas, sobre el uso
inotify
, son correctas, pero no una respuesta a esta pregunta.Un supervisor de proceso, como
supervisord
,upstart
orunit
, está diseñado para el problema exacto de ver y reiniciar un servicio si falla.Su distribución probablemente viene con un supervisor de procesos incorporado.
fuente
while true
está bien como una construcción de "ciclo para siempre" de uso general. Como dicen otras respuestas, el cuerpo del ciclo no debe estar vacío, o volverse vacío en virtud de que el comando dentro del ciclo no funciona.Si está utilizando Linux, es posible que desee utilizar un comando como
inotifywait
, que hace que elwhile
bucle sea mucho más simple:Aquí, el
inotifywait
comando se sentará y esperará a que ocurra un evento del sistema de archivos (en este ejemplo, cuando se escriben los archivos en el directorio). En ese punto, sale con éxito y se ejecuta el cuerpo del bucle. Luego vuelve a esperar de nuevo. Debido a que elinotifywait
comando espera que ocurra algo en el directorio, es mucho más eficiente que sondear continuamente el directorio.fuente
Mueva el while 1 al script perl (Siguiendo la sugerencia de @roaima)
fuente
Cuando su script perl está destinado a seguir ejecutándose todo el tiempo, ¿por qué usar la construcción while? Cuando el perl falla en vista de algún problema grave, la nueva secuencia de comandos perl iniciada por el tiempo podría bloquearse igual de duro. Una y otra vez y así sucesivamente.
si realmente quieres que tu perl comience de nuevo, considera crontab y un script que primero verifica las instancias en ejecución. De esta manera, su script incluso se iniciará después de un reinicio.
fuente
En general, no hay ningún problema al usarlo,
while true
ya que es una pequeña prueba que solo se ejecuta después de que finaliza el script perl. Tenga en cuenta que, según la variante de Linux / Unix que esté utilizando, el script podría finalizar al cerrar la sesión. En tal caso, considere usar el bucle en un script y llámelo connohup
y póngalo en segundo plano, es decirnohup myscript &
Si el script perl termina con demasiada frecuencia y causa una carga de CPU, esta carga es responsable del script perl y no del
while true
.Ver también
man nohup
para más detalles.fuente
Si desea administrar un proceso, es posible que desee buscar un administrador de procesos para hacerlo.
Con muchos sistemas recientes, puede usar systemd para monitorear sus procesos (que es uno de los beneficios de systemd sobre los scripts de inicio clásicos). Si su distribución preferida no usa systemd, puede usar daemontools o monit .
fuente
mon
es una alternativa simple, si la enorme humanidad de monit y systemd te molesta tanto como a mí.El
while
bucle no es realmente una buena idea. No hay escapatoria allí, solo funciona para siempre, estáticamente . Cualquier cantidad de cosas podría cambiar en el medio ambiente y no se verá afectada, y esto podría ser malo.Por ejemplo, si
while
se actualiza el ejecutable del shell responsable de ese ciclo, el kernel no podrá liberar el espacio en disco para la versión anterior hasta que se cierre el script porque necesita mantener el descriptor mientras se ejecuta. Y eso es cierto para cualquier archivo que el shell pueda haber abierto por cualquier razón para ejecutar el bucle; todos se mantendrán abiertos por estewhile
bucle durante el tiempo que se ejecute, para siempre.Y si, Dios no lo quiera, hay una pérdida de memoria en cualquier parte del shell que ejecuta ese bucle, incluso el más mínimo, simplemente continuará perdiendo estáticamente . Se construirá sin control y el único recurso es matarlo a la fuerza, luego comenzar de nuevo solo para hacer lo mismo más tarde.
Esta no es la forma en que debería configurar un proceso en segundo plano, al menos, no en mi opinión. En cambio, como creo, debería haber un punto de reinicio: una actualización del script y su estado. La forma más fácil de hacer esto es con
exec
. Puede reemplazar el proceso actual por uno nuevo, mientras mantiene el mismo PID, pero aún ejecuta un nuevo proceso.Por ejemplo, si su
perl
script debe devolver verdadero después de que haya manejado con éxito una modificación de archivo en algún directorio monitoreado:...o algo así. Algo que permite que la maquinaria básica detrás del bucle se actualice de vez en cuando.
fuente
Voté algunas de estas respuestas, pero instintivamente tengo los sentimientos más cálidos por la respuesta de @ WalterA. Bueno, lo hice hasta que creé mi propia respuesta ...
Personalmente, tiendo a actualizar el script de Perl para que escriba una entrada de registro descriptiva sobre la falla y envíe una alerta a un administrador.
Si el script Perl está destinado a continuar ejecutándose, esperando eventos de cambio del sistema de archivos, ¿por qué falla?
Si no falla, ¿por qué le preocupa envolverlo en un script para reiniciarlo infinitamente?
Si hay un problema de configuración o alguna dependencia rota que hace que el script Perl se cancele, simplemente reiniciarlo una y otra vez no hará que de repente comience a funcionar.
Conoces la definición de locura, ¿verdad? (haciendo lo mismo una y otra vez, esperando un resultado diferente). Solo digo. ;-)
fuente