Come eseguire un comando in background con un ritardo?


33

Qualcuno può mostrarmi come fare un programma per fare questa azione: dopo 5 minuti

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

Voglio che questo programma venga eseguito in background (come il rngdservizio). Non posso farlo perché non so molto su Linux.

Risposte:


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

In questo modo il tuo script continua o ripristini immediatamente il controllo, mentre inizia una nuova attività in background dello script, con due comandi: sleep ed echo.

L'errore comune sta cercando di dare uno sleepo echoo entrambi il &che non funziona come previsto. L'avvio di una serie di comandi ()li genera in un processo di shell separato, che è quindi possibile inviare in background intero &.


A tal proposito, dove l'ho trovato attivamente utile. In un dispositivo incorporato che sviluppo c'è l'applicazione principale che funziona con un cane da guardia. Se fallisce in un modo che innesca il reset del watchdog subito dopo l'avvio, ripetutamente, è difficile risolvere il problema in remoto poiché il periodo tra l'avvio del sistema operativo e il ripristino è piuttosto breve, non abbastanza per entrare e bloccare l'avvio dell'app. Quindi ho bisogno di un modo per determinare il riavvio del sistema così velocemente e introdurre un ritardo, se così fosse, per darmi il tempo di ripararlo manualmente.

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

Se eseguo l'accesso ed eseguo touch /tmp/noautostartl'app principale non si avvierà. Se il cane da guardia interviene, rm /tmp/startdelaynon verrà eseguito e al successivo avvio del sistema, mi daranno 30 secondi in più per fermarlo. Altrimenti il ​​riavvio sarà rapido, senza indugio.


Sì, sono d'accordo, ma può anche far parte della riflessione dell'utente ;-)
Kiwy,

Altre risposte sembrano mancare la parte "in background". No, ero piuttosto esplicito al riguardo: /
goldilocks il

@goldilocks: hai aggiunto l'invio in background solo dopo che ho pubblicato la mia risposta.
SF.

No, la mia risposta originale era eseguire una funzione contenente sleep con &sullo sfondo il sleep; "è necessario anche lo sfondo del sonno" era in prima linea dall'inizio. Se non mi credi, guarda la cronologia delle modifiche. E la mia risposta è di 5 minuti più vecchia della tua: P
Riccioli d'oro

1
@gekannt: ... la domanda è "Come eseguire un comando in background con un ritardo?" - come lo faresti altrimenti? (e no, se non lo sfondo del ()gruppo, la shell originale si fermerà fino a quando quella generata termina.)
SF.

11

usa il atcomando

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

che verrà eseguito in background


2
Questo è il modo giusto per farlo, ma ha bisogno del demone atd in esecuzione e sulla maggior parte dei sistemi dovrà avere un pacchetto installato.
Giuliano

Puoi usare le virgolette singole per evitare la fuga e rinunciare del echotutto usando un heredoc o un herestring.
Chris Down,

@Julian, atè un comando POSIX standard. Quale sistema simile a Unix non lo ha disponibile per impostazione predefinita?
Stéphane Chazelas,

1
@ StéphaneChazelas - buona domanda. so di aver avuto questo problema ma è stato un po 'di tempo fa. Ho fatto un po 'di controllo e il comando at sembra abbastanza onnipresente. Inoltre sembra che atd sia specifico di Linux e anche su alcuni sistemi Linux può essere sostituito da un demone cron in stile BSD. Consideriamo il mio commento obsoleto.
Julian

Ho provato 'at' e nessun comando è stato trovato su Android 8
beppe9000 il

6

Se vuoi eseguire qualcosa in 5 minuti, ma il resto del programma continua (o termina), devi anche mettere in background il sonno:

#!/bin/bash

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

runWithDelay 3 echo world &
echo hello    

Questo verrà stampato helloe quindi 3 secondi dopo (una volta terminato il programma principale), verrà stampato world.

La parte importante è il &fork dell'esecuzione della funzione in background.


1
Posso suggerire runWithDelay () { sleep $1; "${@:2}"; }invece?
arte

1
Penso che dovrebbe leggere doWhateverWithDelay 3 &nel tuo secondo esempio.
Baarn,

@manatwork: Saluti.
riccioli d'oro,

1
@goldilocks, l'essenziale nell'uso $@è che puoi citarlo e verrà espanso come elenco di parole tra virgolette. Quindi meglio farlo "$@"(o "${@}"se ti piacciono le parentesi graffe). Vedi pastebin.com/MU7hbB2C
manatwork,

@manatwork: punto preso;) Ho provato a usare args con echo ( -n), ma ovviamente era un po 'ingenuo.
Riccioli d'oro
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.