49

Can somebody show me how to make a program to do this action: after 5 minutes

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

I want this program run in the background (like rngd service) I can't do this because I don't know so much about Linux.

3 Answers 3

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

That way your script continues, or you restore control immediately, while a new background task of the script starts, with two commands: sleep, and echo.

The common error is trying to give either sleep or echo or both the & which will not work as intended. Launching a series of commands in () though spawns them in a separate shell process, which you can then send whole into background with &.


To that wit, where I found it actively useful. In an embedded device I develop there's the main application that works with a watchdog. If it fails in a way that triggers the watchdog reset soon after startup, repeatedly, it's hard to fix remotely as the period between the OS start and the reset is quite short, not enough to ssh in, and block the app startup. So I need a way to determine the system restarted so fast and introduce a delay if it did, to give myself time to fix it manually.

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

If I log in and perform touch /tmp/noautostart the main app won't start. If the watchdog kicks in, rm /tmp/startdelay won't be performed and the next time the system starts, it will give me extra 30s to stop it. Otherwise restart will be quick, without delay.

8
  • 1
    Yes I agree, but that can also be part of the user reflection ;-)
    – Kiwy
    Nov 28, 2013 at 15:01
  • Other answers seem to miss the "in background" part. No, I was pretty explicit about that :/
    – goldilocks
    Nov 28, 2013 at 15:02
  • @goldilocks: You added the sending into background part only after I posted my answer.
    – SF.
    Nov 28, 2013 at 15:25
  • No, my original answer was to run a function containing sleep with & to background the sleep; "you need to background the sleep as well" was in the first line from the beginning. If you don't believe me, look at the edit history. And my answer is 5 minutes older than yours :P
    – goldilocks
    Nov 28, 2013 at 15:42
  • 1
    @gekannt: ...uh, the question is "How to run a command in the background with a delay?" - how would you achieve it otherwise? (and no, if you don't background the () group, the original shell will pause until the spawned one finishes.)
    – SF.
    Sep 5, 2014 at 11:58
17

use the at command

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

that will run in the background

6
  • 2
    This is the right way to do it, but it does need the atd daemon running and on most systems will need to have a package installed.
    – Julian
    Nov 28, 2013 at 23:17
  • You can use single quotes to avoid the escaping, and forego echo altogether by using a heredoc or herestring.
    – Chris Down
    Dec 2, 2013 at 15:49
  • 1
    @Julian, at is a standard POSIX command. What Unix-like system doesn't have it available by default? Jan 1, 2016 at 14:55
  • 1
    @StéphaneChazelas - good question. i know I've had this problem but it was a while ago. I did a little checking and the at command does seem pretty ubiquitous. Also it seems atd is Linux specific and even on some Linux systems may be replaced by a BSD style cron daemon. Let's consider my comment outdated.
    – Julian
    Jan 1, 2016 at 16:54
  • I tried 'at' and no command was found on Android 8
    – beppe9000
    Oct 28, 2019 at 1:35
7

If you want something to run in 5 minutes, but the rest of your program to continue (or finish), you need to background the sleep as well:

#!/bin/bash

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

runWithDelay 3 echo world &
echo hello    

This will print hello and then 3 seconds later (after the main program has exited), print world.

The important part is the & to fork the function execution into the background.

5
  • 1
    May I suggest runWithDelay () { sleep $1; "${@:2}"; } instead?
    – manatwork
    Nov 28, 2013 at 15:00
  • 1
    I think it should read doWhateverWithDelay 3 & in your second example.
    – Baarn
    Nov 28, 2013 at 15:01
  • @manatwork : Cheers.
    – goldilocks
    Nov 28, 2013 at 15:06
  • 1
    @goldilocks, the essential in using $@ is that you can quote it and will be expanded as list of quoted words. So better make it "$@" (or "${@}" if you like the braces). See pastebin.com/MU7hbB2C
    – manatwork
    Nov 28, 2013 at 15:15
  • 1
    @manatwork : Point taken ;) I did try that using args with echo (-n), but obviously that was a bit naive.
    – goldilocks
    Nov 28, 2013 at 20:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.