Uso el servidor Ubuntu 16.04 y deseo usar la utilidad aten mi sesión actual para hacer algo dentro de 1 minuto (digamos, un echo), sin dar una fecha y hora específicas, solo 1 minuto antes de la hora actual.
Esto falló:
echo 'hi' | at 1m
La razón por la que elijo atmás sleepes porque el sueño perjudica la sesión actual y, por lo tanto, es más adecuado para retrasar los comandos en otra sesión, en lugar de con la que trabajamos la mayor parte del tiempo. AFAIR, atno se comporta de esta manera y no perjudicará mi sesión.
Actualización_1
Por la respuesta de Pied Piper, he intentado:
(sleep 1m; echo 'hi') &
Tengo un problema con este método: la secuencia "hola" se imprime dentro de mi mensaje principal y también agrega un mensaje secundario vacío ( _) justo debajo del mensaje principal que lo contiene, vea:
USER@:~# (sleep 1m; echo 'hi') &
[1] 22731
USER@:~# hi
^C
[1]+ Done
Actualización_2
Por la respuesta de Peter Corde intenté:
(sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)
Esto funciona correctamente en Bash 4.4, pero no en algunas versiones anteriores, aparentemente (ver comentarios en la respuesta). Yo personalmente uso Bash 4.3 en mis propios entornos.

Respuestas:
No, es no "impreso en su
stdin".Si presionó Intro, no intentaría ejecutarse
hicomo un comando. Es solo que el fondo seechoimprimióhimientras el cursor estaba después de su solicitud.Quizás desee imprimir una nueva línea principal , como
(sleep 1m && echo -e '\nhi' &). (Ajuste según sea necesario para elechoen su shell. O useprintfpara la portabilidad).Puse el
&interior del subshell para "rechazar" el trabajo en segundo plano, para que también evite el "ruido" de[1]+ Done. Con&&entre los comandos, se&aplica a toda la cadena de comandos compuestos, por lo que vuelve al indicador de comandos de inmediato en lugar de esperarsleepa salir como lo haría con(sleep 1; echo ... &)Esto es lo que sucede (con 1 segundo de retraso):
Bash no sabe que
echoimprimió algo, por lo que no sabe que necesita volver a imprimir su mensaje o limpiar la pantalla. Puede hacerlo manualmente concontrol-L.Podría escribir una función de shell que obtenga bash para volver a imprimir su solicitud después de
echofinalizar . Hacerloecho "$PS1"no reproducirá ningún carácter ya escrito.kill -WINCH $$en mi sistema, bash vuelve a imprimir su línea de aviso sin borrar la pantalla, dejandohiuna línea sola antes del aviso. SIGWINCH se envía automáticamente cuando el tamaño de WINdow cambia, y la respuesta de bash hace lo que queremos.Puede funcionar con otros shells, pero no estoy tratando de hacer que este sea 100% portátil / POSIX. ( Desafortunadamente, esto solo funciona en bash4.4, no bash4.3, o depende de alguna configuración que desconozco )
Podría envolver esto fácilmente en una función de shell que toma un argumento de suspensión y un mensaje.
bash 4.3 no vuelve a imprimir su solicitud después de SIGWINCH, por lo que esto no funciona allí. He
shopt -s checkwinsizehabilitado en ambos sistemas, pero solo funciona en el sistema Bash 4.4 (Arch Linux).Si no funciona, puede intentarlo
(sleep 2 && echo -e '\nhi' && echo "$PS1" &), lo que "funciona" si la línea de comando está vacía. (También ignora la posibilidad quePROMPT_COMMANDse establece).No hay una forma realmente limpia de hacer que la salida del terminal se mezcle con lo que sea que esté haciendo en su terminal más tarde, cuando se dispara el temporizador. Si estás en medio de desplazarte por algo
less, podrías pasarlo por alto fácilmente.Si está buscando algo con resultados interactivos, le sugiero que reproduzca un archivo de audio. por ejemplo, con un jugador de línea de comandos como
mpv(buen fork de MPlayer2). O elija un archivo de video para que se abra una nueva ventana.Es posible que desee
echoabrir un nuevo xterm / konsole / gnome-terminal. Use una opción que mantenga el terminal abierto después de que salga el comando.fuente
Enterevento de pulsación de tecla, justo después de que aparezca el eco, para que automáticamente vuelva al indicador principal de la consola ?(sleep 2 && echo -e '\nhi' && kill -WINCH $$ &).kill -WINCH $$no actualizar el símbolo de la concha se ejecuta en el terminal. Ese era el punto de usarlo. Al presionar enter se enviaría un comando parcialmente escrito, pero WINCH no, como lo mostré. Si no ha escrito nada, aparece un mensaje vacío.rm -rf ~/some/directory, entrar en el momento incorrecto podría ejecutarserm -rf ~/. (Consejo de seguridad: termine de escribir los trazados y luego controle-a y cambielsarm -rf, por lo que ingresar con dedos gordos Enter en cualquier momento no arruinará su día.)(sleep 2 && echo -e '\nhi' && kill -WINCH $$ &)y después de que apareció el eco, recibí un mensaje vacío, solo después de presionarEntervolví al mensaje principal ... Lo siento si no te entiendo, soy bastante nuevo en Bash.screensesión (y solo a través de SSH) en un sistema Ubuntu más antiguo, y obtuve el comportamiento que usted describe.Lo correcto en el uso es
at <timespec>dónde<timespec>está la especificación de tiempo. También puede usar la-fopción para especificar el archivo que contiene los comandos para ejecutar. Si-fno se utiliza la redirección, leerá los comandos para ejecutar desde el stdin (entrada estándar).En su ejemplo, para ejecutar "algún comando" (elegí "algún comando" para que sea "echo hola" en el ejemplo a continuación) un minuto después de presionar enter (ahora), lo que se pretende
<timespec>usar esnow + 1 minute. Entonces, para obtener el resultado que desea con una solución de una sola línea, utilice el siguiente comando:echo 'echo hi' | at now + 1 minuteEsto se supone (y lo hará) para ejecutar el
echo hicomando después de un minuto. El problema aquí es que elecho hicomando será ejecutado por el comando at en un tummy ficticio y la salida se enviará al buzón del usuario (si está configurada correctamente), lo que requiere una explicación más amplia sobre cómo configurar un buzón en una máquina unix y no es parte del alcance de esta pregunta). La conclusión es que no podrá ver directamente el resultadoecho hien el mismo terminal en el que emitió el comando. La alternativa más fácil es redirigirlo a "algún archivo", por ejemplo:echo 'echo hi > /tmp/at.out' | at now + 1 minuteEn el ejemplo anterior, "algún archivo" es
/tmp/at.outy el resultado esperado es que el archivoat.outbajo / tmp se crea después de un minuto y contiene el texto 'hola'.Además del
now + 1 minuteejemplo anterior, se pueden usar muchas otras especificaciones de tiempo, incluso algunas complejas. El comando at es lo suficientemente inteligente como para interpretar los que son legibles para humanos como los ejemplos a continuación:now + 1 day`13:25`mid‐night`noon` ...Consulte la página de manual de at para obtener más información sobre las posibles especificaciones de tiempo, ya que las posibles variaciones son bastante extensas y pueden incluir fechas, tiempos relativos o absolutos, etc.
fuente
atde forma predeterminada, envía la salida por correo, pero debe configurarse correctamente para funcionar.at <timespec>y la bandera que utilizó y si se ajusta a Ubuntu 16.04 xenial.Ejecute el
sleepen una subshell:Nota: en Linux puede dar el argumento para dormir en segundos o con un sufijo s / m / h / d (por segundos, minutos, horas, días). En BSD el argumento tiene que estar en segundos
fuente
stdin) y no en mistdout(como lo haría con un mensaje regularecho).(sleep 10s; echo 'hi') & 1>. Ahora leo más sobre esto.stdinystdout. No tienen nada que ver con dónde aparecen las cosas en su terminal; en su lugar, debe interpretarlos con respecto a un proceso particular (básicamente, un programa). La entrada estándar ("stdin") para un proceso es una fuente desde la cual el proceso puede leer datos, y la salida estándar del proceso ("stdout") es un destino en el que puede escribir datos. Estas fuentes y destinos pueden ser otros programas o archivos, o el terminal en sí (las cosas que escribe van a stdin y se muestra todo lo que viene a stdout).Eso falló porque está canalizando la salida de
echo "hi", que es solohiparaat, peroatespera que su entrada pueda ejecutarse mediante el shell del sistema predeterminado (generalmente bash, pero a veces algo diferente dependiendo del sistema).Esta:
logrará lo que parece estar tratando de hacer. Utiliza una construcción de shell llamada 'documento aquí', que generalmente es la forma aceptada de hacer este tipo de cosas (porque maneja varias líneas mejor que usar el
echocomando y no requiere crear un nuevo archivo como lo necesitaría concat), y se traduce al equivalente algo más complicado usandoecho:Probablemente valga la pena señalar que
atenviará cualquier salida de comando al usuario que invocó elatcomando, en lugar de enviar la salida al terminal como losleepharía un comando retrasado al usarlo en una subshell. En particular, esto significa que a menos que haya realizado alguna personalización del sistema o tenga la intención de leer su cola de correo local, no podrá obtener la salida de los comandos a través deat.fuente
syntax error. Last token seen: m Garbled time. No tengo ni idea de porqué. Yo uso Ubuntu 16.04, Bash 4.0. Tal vez lo hiciste en otro sistema. Incluso cuando escriboatsin más argumentos --- sigo teniendo este mismo error. Más datos aquí .at 1mno funciona para un posix compatibleat. El comando debería serat now + 1 minuteat, solo estaba asumiendo que tenía una versión que aceptaba esa sintaxis.at 1mno es POSIX, pero las implementaciones compatibles con POSIXatson libres de interpretarlo como lo deseen, no hace que unaatimplementación sea menos compatible para interpretarlo con el mismo significadonow + 1 minuteque devolver un error o significado hace un mes . IOW, es elat 1mcódigo que no es POSIX.Combine la respuesta de @Peter Cordes y esta respuesta /programming/23125527/how-to-return-to-bash-prompt-after-printing-output-from-backgrounded-function/23125687#23125687
El siguiente código es de la última respuesta, con un pequeño cambio mío. Compílalo para archivar a.out (como quieras)
Luego ejecute el comando a continuación. (Puse a.out en dir / tmp /, es posible que deba cambiar el suyo)
o
Por cierto,
kill -WINCH $$funciona bien para mí con Bash 4.3 en Gentoo.fuente
Sobre la base de las respuestas anteriores, puede hacer que el comando incrustado dirija su salida a su terminal, así:
echo "echo hi >$(tty); kill -WINCH $$" | at now + 1 minuteEl
ttycomando devuelve la ruta del dispositivo de su terminal actual, encerrándolo en$(...)bash, ejecútelo en un sub-shell, y el comando kill envía una señal al proceso actual que hará que bash vuelva a imprimir su solicitud $ PS1.fuente