Shell: é possível atrasar um comando sem usar o `sleep`?
772
Existem substitutos, alternativas ou truques bash para atrasar comandos sem usar sleep? Por exemplo, executando o comando abaixo sem realmente usar sleep:
Para dormir por 10 segundos sem usar sleep. O coprocobjetivo é fazer com que reado stdin seja um tubo de onde nada saia. || trueé porque waito status de saída de 's refletirá uma entrega SIGALRM que faria com que o shell saísse se a errexitopção fosse definida.
Em outras conchas:
mkshe ksh93tem sleepbuilt-in, não faz sentido usar mais nada lá (embora ambos também suportem read -t).
zshtambém suporta read -t, mas também possui um wrapper embutido em torno select()de , então você também pode usar:
Você tem alternativas para sleep: Eles são ate cron. Ao contrário sleepdisso, você precisa fornecer o horário em que precisa que eles sejam executados.
Verifique se o atdserviço está sendo executado executando service atd status.
Agora, digamos que a data seja 11h17 UTC; se você precisar executar um comando às 11:25 UTC, a sintaxe é: echo "This is a test" | at 11:25.
Agora tenha em mente que atdpor padrão não estará registrando a conclusão dos trabalhos. Para mais consulte este link . É melhor que seu aplicativo tenha seu próprio registro.
Você pode agendar trabalhos em cron, para mais consulte : man cronpara ver suas opções ou crontab -epara adicionar novos trabalhos. /var/log/cronpode ser verificado para obter as informações sobre a execução em trabalhos.
FYI sleep system call suspende a execução atual e a agenda com o argumento passado para ela.
EDITAR:
Como o @Gaius mencionou, você também pode adicionar minutos ao comando. Mas atdigamos que o tempo é 12:30:30e agora você executou o agendador com now +1 minutes. Mesmo que 1 minuto, que se traduz em 60 segundos, tenha sido especificado , atele realmente não espera até 12:31:30executar o trabalho, mas executa o trabalho em 12:31:00. As unidades de tempo podem ser minutes, hours, days, or weeks. Para mais consulteman at
Nos dias dos microcomputadores rodando BASIC, os atrasos eram geralmente realizados com um loop vazio:
FOR I = 1 TO 10000:NEXT
O mesmo princípio pode ser usado para inserir um atraso em um script de shell:
COUNTER=0; while [ $COUNTER -lt 10000 ]; do :; let COUNTER=COUNTER+1; done
Obviamente, o problema com essa abordagem é que a duração do atraso varia de máquina para máquina de acordo com a velocidade do processador (ou mesmo na mesma máquina sob cargas diferentes). Ao contrário sleepde , provavelmente também maximizará sua CPU (ou um de seus núcleos).
Com
bash
builtins, você pode fazer:Para dormir por 10 segundos sem usar
sleep
. Ocoproc
objetivo é fazer com queread
o stdin seja um tubo de onde nada saia.|| true
é porquewait
o status de saída de 's refletirá uma entrega SIGALRM que faria com que o shell saísse se aerrexit
opção fosse definida.Em outras conchas:
mksh
eksh93
temsleep
built-in, não faz sentido usar mais nada lá (embora ambos também suportemread -t
).zsh
também suportaread -t
, mas também possui um wrapper embutido em tornoselect()
de , então você também pode usar:Se o que você deseja é agendar as coisas para serem executadas a partir de uma sessão de shell interativa, consulte também o
zsh/sched
módulo emzsh
.Você tem alternativas para
sleep
: Eles sãoat
ecron
. Ao contráriosleep
disso, você precisa fornecer o horário em que precisa que eles sejam executados.Verifique se o
atd
serviço está sendo executado executandoservice atd status
.Agora, digamos que a data seja 11h17 UTC; se você precisar executar um comando às 11:25 UTC, a sintaxe é:
echo "This is a test" | at 11:25
.Agora tenha em mente que
atd
por padrão não estará registrando a conclusão dos trabalhos. Para mais consulte este link . É melhor que seu aplicativo tenha seu próprio registro.Você pode agendar trabalhos em
cron
, para mais consulte :man cron
para ver suas opções oucrontab -e
para adicionar novos trabalhos./var/log/cron
pode ser verificado para obter as informações sobre a execução em trabalhos.FYI
sleep system call
suspende a execução atual e a agenda com o argumento passado para ela.EDITAR:
Como o @Gaius mencionou, você também pode adicionar minutos ao comando. Mas
at
digamos que o tempo é12:30:30
e agora você executou o agendador comnow +1 minutes
. Mesmo que 1 minuto, que se traduz em 60 segundos, tenha sido especificado ,at
ele realmente não espera até12:31:30
executar o trabalho, mas executa o trabalho em12:31:00
. As unidades de tempo podem serminutes, hours, days, or weeks
. Para mais consulteman at
por exemplo:
echo "ls" | at now +1 minutes
Algumas outras ideias.
Como há respostas sugerindo o uso da
-t delay
opção não padrão deread
, aqui está uma maneira de fazer uma leitura expirada em um shell padrão:O argumento para
stty time
está em décimos de segundo.Usando a variável interna do bash
$SECONDS
e um loop ocupado:Nos dias dos microcomputadores rodando BASIC, os atrasos eram geralmente realizados com um loop vazio:
FOR I = 1 TO 10000:NEXT
O mesmo princípio pode ser usado para inserir um atraso em um script de shell:
COUNTER=0; while [ $COUNTER -lt 10000 ]; do :; let COUNTER=COUNTER+1; done
Obviamente, o problema com essa abordagem é que a duração do atraso varia de máquina para máquina de acordo com a velocidade do processador (ou mesmo na mesma máquina sob cargas diferentes). Ao contrário
sleep
de , provavelmente também maximizará sua CPU (ou um de seus núcleos).o truque mais antigo do livro:
Basta bater Entere ele vai continuar!
Não há built-in, que faz o mesmo que
sleep
(a menos quesleep
seja built-in). No entanto, existem alguns outros comandos que irão esperar.Alguns incluem.
at
ecron
: usado para agendar tarefas em um horário específico.inotifywait
: usado para esperar um arquivo ou arquivos serem modificados/removidos/adicionados/etcUm clássico da Terra das Janelas e dos Lotes:
Se você quiser esperar interativamente por uma nova linha em um arquivo, então
.Esperando por uma mudança em um sistema de arquivos? Então use por exemplo
.E existem outras opções, dependendo do que você quer dizer com "esperar".