Como executar um comando em segundo plano com um atraso?

33

Alguém pode me mostrar como criar um programa para executar esta ação: após 5 minutos

echo "80" > /sys/class/leds/blue/brightness

Quero que este programa seja executado em segundo plano (como rngdserviço). Não posso fazer isso porque não sei muito sobre Linux.

user53337
fonte

Respostas:

51
( sleep 300 ; echo "80" > /sys/class/leds/blue/brightness ) &

Dessa forma, seu script continua ou você restaura o controle imediatamente, enquanto uma nova tarefa em segundo plano do script é iniciada, com dois comandos: suspensão e eco.

O erro comum é tentar dar tanto sleepou echoou ambos o &que não vai funcionar como pretendido. O lançamento de uma série de comandos os ()gera em um processo de shell separado, com o qual você pode enviar todo em segundo plano &.


Nesse sentido, onde eu o achei ativamente útil. Em um dispositivo incorporado que desenvolvo, há o aplicativo principal que funciona com um cão de guarda. Se ele falhar de uma maneira que acione a redefinição do watchdog logo após a inicialização, repetidamente, é difícil corrigir remotamente, pois o período entre o início do sistema operacional e a redefinição é bastante curto, não é suficiente para sincronizar e bloquear a inicialização do aplicativo. Então, eu preciso de uma maneira de determinar o sistema reiniciado tão rápido e introduzir um atraso, se houver, para me dar tempo para corrigi-lo manualmente.

 [ -f /tmp/startdelay ] && sleep 30
 touch /tmp/startdelay
 ( sleep 30 ; rm /tmp/startdelay ) &
 [ -f /tmp/noautostart ] && exit 0
 start_app

Se eu efetuar login e executar touch /tmp/noautostarto aplicativo principal, não será iniciado. Se o cão de guarda rm /tmp/startdelayentrar em ação, não será executado e na próxima vez que o sistema for iniciado, me dará 30s extras para pará-lo. Caso contrário, o reinício será rápido, sem demora.

SF.
fonte
Sim, eu concordo, mas que também pode ser parte do usuário reflexão ;-)
kiwy
Outras respostas parecem faltar na parte "em segundo plano". Não, eu fui bem explícito sobre isso: /
goldilocks 28/11
@ goldilocks: você adicionou o envio na parte de segundo plano somente depois que eu postei minha resposta.
SF.
Não, minha resposta original foi executar uma função que continha o sono com o &fundo para dormir; "você também precisa dormir em segundo plano" estava na primeira linha desde o início. Se você não acredita em mim, veja o histórico de edições. E minha resposta é de 5 minutos mais velho do que sua: P
Goldilocks
1
@gekannt: ... uh, a pergunta é "Como executar um comando em segundo plano com um atraso?" - como você conseguiria isso de outra maneira? (e não, se você não formar um plano de fundo para o ()grupo, o shell original será pausado até que o desovado termine.)
SF.
11

use o atcomando

echo "echo \"80\" > /sys/class/leds/blue/brightness" | at now + 5 min

que será executado em segundo plano

exussum
fonte
2
Esta é a maneira correta de fazê-lo, mas ele precisa do daemon atd em execução e na maioria dos sistemas precisará ter um pacote instalado.
Julian
Você pode usar aspas simples para evitar a fuga e renunciar echocompletamente usando um heredoc ou herestring.
Chris Baixo
@ Julian, até um comando POSIX padrão. Qual sistema Unix-like não o tem disponível por padrão?
Stéphane Chazelas
1
@ StéphaneChazelas - boa pergunta. Eu sei que tive esse problema, mas foi há um tempo atrás. Eu fiz uma pequena verificação e o comando at parece bastante onipresente. Também parece que o atd é específico do Linux e, mesmo em alguns sistemas Linux, pode ser substituído por um daemon cron no estilo BSD. Vamos considerar meu comentário desatualizado.
Julian
Tentei 'at' e nenhum comando foi encontrado no Android 8
beppe9000 28/10
6

Se você deseja que algo seja executado em 5 minutos, mas o restante do seu programa continue (ou termine), você também precisará adormecer:

#!/bin/bash

runWithDelay () {
    sleep $1;
    shift;
    "${@}";
}

runWithDelay 3 echo world &
echo hello    

Isso será impresso helloe, em seguida, 3 segundos depois (após a saída do programa principal), imprima world.

A parte importante é &colocar a execução da função em segundo plano.

Cachinhos Dourados
fonte
1
Em runWithDelay () { sleep $1; "${@:2}"; }vez disso , posso sugerir ?
manatwork
1
Eu acho que deveria ler doWhateverWithDelay 3 &no seu segundo exemplo.
Baarn 28/11
@manatwork: Saúde.
Goldilocks
1
@goldilocks, o essencial no uso $@é que você pode citá-lo e será expandido como uma lista de palavras citadas. Então é melhor fazê-lo "$@"(ou "${@}"se você gosta do aparelho). Veja pastebin.com/MU7hbB2C
manatwork
@manatwork: Point taken;) Eu tentei isso usando args com echo ( -n), mas obviamente isso foi um pouco ingênuo.
Goldilocks