Uso el servidor Ubuntu 16.04 y deseo usar la utilidad at
en 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 at
más sleep
es 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, at
no 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
hi
como un comando. Es solo que el fondo seecho
imprimióhi
mientras 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 elecho
en su shell. O useprintf
para 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 esperarsleep
a salir como lo haría con(sleep 1; echo ... &)
Esto es lo que sucede (con 1 segundo de retraso):
Bash no sabe que
echo
imprimió 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
echo
finalizar . 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, dejandohi
una 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 checkwinsize
habilitado 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_COMMAND
se 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
echo
abrir un nuevo xterm / konsole / gnome-terminal. Use una opción que mantenga el terminal abierto después de que salga el comando.fuente
Enter
evento 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 cambiels
arm -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 presionarEnter
volví al mensaje principal ... Lo siento si no te entiendo, soy bastante nuevo en Bash.screen
sesió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-f
opción para especificar el archivo que contiene los comandos para ejecutar. Si-f
no 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 minute
Esto se supone (y lo hará) para ejecutar el
echo hi
comando después de un minuto. El problema aquí es que elecho hi
comando 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 hi
en 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 minute
En el ejemplo anterior, "algún archivo" es
/tmp/at.out
y el resultado esperado es que el archivoat.out
bajo / tmp se crea después de un minuto y contiene el texto 'hola'.Además del
now + 1 minute
ejemplo 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
at
de 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
sleep
en 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.stdin
ystdout
. 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 solohi
paraat
, peroat
espera 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
echo
comando 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
at
enviará cualquier salida de comando al usuario que invocó elat
comando, en lugar de enviar la salida al terminal como losleep
harí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 escriboat
sin más argumentos --- sigo teniendo este mismo error. Más datos aquí .at 1m
no funciona para un posix compatibleat
. El comando debería serat now + 1 minute
at
, solo estaba asumiendo que tenía una versión que aceptaba esa sintaxis.at 1m
no es POSIX, pero las implementaciones compatibles con POSIXat
son libres de interpretarlo como lo deseen, no hace que unaat
implementación sea menos compatible para interpretarlo con el mismo significadonow + 1 minute
que devolver un error o significado hace un mes . IOW, es elat 1m
có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 minute
El
tty
comando 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