Soy un novato relativo de Linux. Estoy tratando de aprender a usar at
para poder programar tareas para que comiencen más tarde, sin usar sleep
. He estado mirando esta pregunta anterior en busca de ayuda.
Mi pregunta es, en el siguiente script de bash de muestra que he creado, ¿por qué "Running" nunca, por lo que puedo decir, se imprime en la salida estándar (es decir, mi consola bash)?
#!/bin/bash
echo "Started"
at now + 1 minutes <<EOF
echo "Running"
EOF
echo "Finished"
El único resultado que veo es, por ejemplo:
Started warning: commands will be executed using /bin/sh job 3 at Fri Jul 12 17:31:00 2013 Finished
¿La respuesta a mi pregunta se encuentra en la advertencia? Si es así, ¿en qué se /bin/sh
diferencia de la salida estándar?
sleep 3m; echo Running
Respuestas:
Porque
at
no ejecuta comandos en el contexto de su sesión de usuario conectada. La idea es que puede programar un comando para que se ejecute en un momento arbitrario, luego cierre la sesión y el sistema se encargará de ejecutar el comando a la hora especificada.Tenga en cuenta que la página del manual
at(1)
dice específicamente (mi énfasis):Por lo tanto, debe verificar su cola de correo local o, en su defecto, los registros de correo del sistema local. / var / spool / mail / $ USER es probablemente un buen lugar para comenzar.
También tenga en cuenta que "Comenzado" y "Finalizado" se originan en el guión externo y en sí mismos no tienen nada que ver
at
en absoluto. Podría sacarlos o laat
invocación y obtendrá esencialmente el mismo resultado.fuente
Como @ MichaelKjörling lo ha explicado, cualquier salida producida por su
at
trabajo será capturada y enviada a usted por correo electrónico. Si no tiene un MTA - Mail Transfer Agent en ejecución en su casilla, entonces el correo electrónico puede estar en el limbo y no sabrá queat
incluso está intentando hacerlo.Una MTA, es un programa como
sendmail
opostfix
que puede "entregar" correos electrónicos a un destino apropiado. En este caso, lo entregará a una cola de correo (un archivo en el directorio/var/spool/mail
) en su sistema local. Cada usuario en el sistema puede tener una cola en este directorio.En mi sistema Fedora, si inicio,
sendmail
puede ocurrir una entrega de correo local. Aunque normalmente lo tengo apagado.Ahora podemos ver que mi cola de correo para mi cuenta de usuario
saml
está vacía:Entonces ahora corremos el
at
trabajo:Podemos ver que el trabajo está esperando para ejecutarse con
atq
:Al ejecutarlo nuevamente después de un par de minutos, podemos ver que el
at
trabajo está completo:Por cierto, con mi MTA ejecutándose ahora recibo este mensaje en mi terminal:
Así que veamos:
Sí, tenemos correo, así que echemos un vistazo usando
mutt
:Tenemos esto en la "bandeja de entrada" de nuestra cola de correo:
Echemos un vistazo a este correo electrónico:
Y funcionó.
fuente
Estoy ejecutando Debian 8.1 (jessie)
Puede hacer que la salida 'at' vaya a una terminal usando tty.
Un minuto después, y 'ZZZZZ' aparecerá en su terminal ...
fuente
Las respuestas anteriores son la forma estándar / "correcta" de hacerlo.
Otro enfoque más simple desde un punto de vista más de "usuario final" es hacer que cualquier tarea programada o en segundo plano escriba su salida en un archivo "log". El archivo puede estar en cualquier parte de su sistema, pero si la tarea se ejecuta como root (desde
cron
, etc.), entonces en algún lugar debajo/var/log
es un buen lugar para colocarlo.Creé el
/var/log/maint
directorio y lo hice legible para todos y tengo un archivo legible debajo de eso llamado "copia de seguridad" donde registro la salida de mis scripts de copia de seguridad.Creé mi propio directorio para que mis archivos no se mezclen con las cosas generadas por el sistema.
Para poner cosas allí (en bash):
Esto
>>
hace que los mensajes se agreguen al archivo en lugar de sobrescribirlo cada vez.Si mi script tiene mucha salida, uso una secuencia de comandos o función para la salida para que todo se haga igual. A continuación se muestra mi versión actual (overkill): (el material VERBOSE está ahí para cuando estoy ejecutando el script desde una terminal y quiero ver lo que está sucediendo con fines de depuración).
Editar:
at
ejemplo simplista que escribe en un archivo de usuarioNo he usado esto para siempre, así que lo descubrí con un par de guiones simples.
El primer script simplemente programa el evento usando
at
. El comando en sí solo podría escribirse en un terminal, pero soy flojo, especialmente cuando tengo que hacerlo varias veces mientras lo pruebo sin engañar con el historial de comandos.El segundo script es el que está programado para ejecutarse.
Creé ambos scripts en un editor de texto, los guardé y luego los hice ejecutables usando
chmod 700 script-file-name
. Los puse a ambos en mi$HOME/bin
directorio por conveniencia, pero podrían estar en cualquier lugar donde mi usuario tenga acceso completo. Lo uso700
para cualquier script que sea solo para pruebas, pero en un solo sistema de usuario, podría serlo755
.Ya tengo un directorio llamado
/home/bigbird/log
para guardar la salida demytest_at_script
. Esto también puede estar en cualquier lugar donde su usuario tenga acceso completo. Solo asegúrese de que exista antes de que se ejecute el script o haga que el script lo cree.Para ejecutarlo, solo me aseguré de que el tiempo para el
at
comandomytest_at_run
fuera un poco en el futuro y luego lo ejecuté desde una terminal. Luego esperé hasta que corrió y examiné el contenido de$HOME/log/at.log
.Algunas notas
Aunque estoy ejecutando
at
desde mi usuario, no conoce mi entorno, como miPATH
y mi directorio personal, por lo que no asumo eso. Utilizo caminos completos como lo haría para cualquiercron
trabajo. Y si alguna vez quiero que sea uncron
trabajo, no tendré que cambiar nada solo para que funcione.He utilizado
>>
enmytest_at_script
a adjuntar la salida al archivo de registro en lugar de>
lo que habría reemplazado en cada carrera. Use el que mejor se adapte a su aplicación.fuente
at
para escribir en un archivo. Parece que tienes la secuencia de llamada al revés en tu ejemplo. No soy muy bueno para decirat
cuándo ejecutar el trabajo, así que solo codifiqué un momento en un futuro muy cercano.