Are there any substitutes, alternatives or bash tricks for delaying commands without using sleep? For example, performing the below command without actually using sleep:

$ sleep 10 && echo "This is a test"
  • 43
    What's wrong with sleep?
    – muru
    Nov 19 '18 at 10:55
  • 5
    There's no real reason other than curiosity. I thought it would be interesting to learn some alternative solutions. I think at might be one, but I couldn't find any usage examples.
    – user321697
    Nov 19 '18 at 11:11
  • 1
    @user321697 “at” is to schedule single jobs. they are executed by the atd service, so they won’t pause your shell script. one use case for at would be to have it do something at a specified time (async) and create a marker file when it’s finished, while your script is waiting for that file to appear in a while loop. you could achieve a similar effect by scheduling a job to send your script a SIGCONT and then freezing your script by sending yourself a SIGSTOP. Nov 19 '18 at 11:13
  • 1
    I came here expecting everyone to suggest a spinlock. I'm pleasantly surprised by all the answers. Nov 19 '18 at 15:59
  • 4
    Re: "Curiosity" -- in unix.stackexchange.com/help/dont-ask, note the requirement that "You should only ask practical, answerable questions based on actual problems that you face." -- that this has been well-received despite controvening that guideline makes it a rather rare exception. Nov 21 '18 at 1:02

10 Answers 10


With bash builtins, you can do:

coproc read -t 10 && wait "$!" || true

To sleep for 10 seconds without using sleep. The coproc is to make so that read's stdin is a pipe where nothing will ever come out from. || true is because wait's exit status will reflect a SIGALRM delivery which would cause the shell to exit if the errexit option is set.

In other shells:

mksh and ksh93 have sleep built-in, no point in using anything else there (though they both also support read -t).

zsh also supports read -t, but also has a builtin wrapper around select(), so you can also use:

zmodload zsh/zselect
zselect -t 1000 # centiseconds

If what you want is schedule things to be run from an interactive shell session, see also the zsh/sched module in zsh.

  • 2
    Would you consider read -t 10 < /dev/zero || true ?
    – Jeff Schaller
    Nov 19 '18 at 14:22
  • 6
    @JeffSchaller I would avoid it as that's a busy loop. Nov 19 '18 at 14:23
  • 6
    @NormanGray, /dev/zero is a file that contains an infinite amount of data (NUL bytes). So read will read as much as it can during those 10 seconds. Thankfully, in the case of bash which doesn't support storing NUL bytes in its variables, that won't use up any memory, but that will still hog CPU resources. Nov 19 '18 at 15:44
  • 1
    @StéphaneChazelas Ach, I'm an idiot! I was looking at the read -t and not at the /dev/zero. My first thought on seeing this question was 'read from a pipe to which nothing is written, or some other input which will never produce bytes, and time out,' and @JeffSchaller's answer looked like he'd had the same thought. It occurs to me that read -t 10 </dev/stdout || true would work (though I can't help feeling that's cheating). Nov 19 '18 at 15:57
  • 2
    @NormanGray, if run from a terminal, /dev/stdout would be the tty device, so it would have side effects (like stopping the script if run in background) and would return if the user presses enter for instance. read -t 10 /dev/stdout | : would work on Linux, but on Linux only, while coproc should work regardless of the OS. Nov 19 '18 at 16:10

You have alternatives to sleep: They are at and cron. Contrary to sleep these need you to provide the time at which you need them to run.

  • Make sure the atd service is running by executing service atd status.
    Now let's say the date is 11:17 am UTC; if you need to execute a command at 11:25 UTC, the syntax is: echo "This is a test" | at 11:25.
    Now keep in mind that atd by default will not be logging the completion of the jobs. For more refer this link. It's better that your application has its own logging.

  • You can schedule jobs in cron, for more refer : man cron to see its options or crontab -e to add new jobs. /var/log/cron can be checked for the info on execution on jobs.

FYI sleep system call suspends the current execution and schedules it w.r.t. the argument passed to it.


As @Gaius mentioned , you can also add minutes time to at command.But lets say time is 12:30:30 and now you ran the scheduler with now +1 minutes. Even though 1 minute, which translates to 60 seconds was specified , the at doesn't really wait till 12:31:30 to execute the job, rather it executes the job at 12:31:00. The time-units can be minutes, hours, days, or weeks. For more refer man at

e.g: echo "ls" | at now +1 minutes

  • 7
    This is not true, you can schedule an at job for say now +1 minute, to run in a minutes time
    – Gaius
    Nov 19 '18 at 16:48

Some other ideas.

top -d10 -n2 >/dev/null

vmstat 10 2 >/dev/null

sar 10 1 >/dev/null

timeout 10s tail -f /dev/null
  • 1
    You "stole" my idea of timelimit/timeout.... +1 Nov 20 '18 at 11:36
  • 1
    Ohhhh my, thanks, I was in a situation without sleep, top is amazing! Feb 8 '19 at 1:58

Since there are answers which are suggesting to use the non-standard -t delay option of read, here is a way to do a timed-out read in a standard shell:

{ ss=`stty -g`; stty -icanon min 0 time 20; read foo; stty "$ss"; }

The argument to stty time is in tenths of second.


Using the bash built-in variable $SECONDS and a busy-loop:

for((target=$((SECONDS + 10)); SECONDS < target; true)); do :; done
  • 2
    That would in effect pause for a duration ranging somewhere in between 9 and 10 seconds though (due to a bug in bash; zsh and mksh had similar issues but have been fixed since) Nov 19 '18 at 14:05
  • 7
    A good way to make heat. Nov 19 '18 at 14:50
  • 7
    won't be the first time I'm accused of being full of hot air! :)
    – Jeff Schaller
    Nov 19 '18 at 14:51

Back in the days of microcomputers running BASIC, delays were usually accomplished with an empty loop:

FOR I = 1 TO 10000:NEXT

The same principle could be used to insert a delay in a shell script:

COUNTER=0; while [ $COUNTER -lt 10000 ]; do :; let COUNTER=COUNTER+1; done

Of course, the problem with this approach is that the length of the delay will vary from machine to machine according to its processor speed (or even on the same machine under different loads). Unlike sleep, it will probably also max out your CPU (or one of its cores).

  • 2
    A good way to make heat. Nov 19 '18 at 14:50
  • 2
    Delay-loops are a terrible idea for anything except the very shortest of sleeps (a couple nanoseconds or clock cycles in a device driver) on any modern CPU that can run a Unix-like OS. i.e. a sleep so short you can't usefully have the CPU do anything else while waiting, like schedule another process or enter a low-power sleep state before waking on a timer interrupt. Dynamic CPU-frequency makes it impossible to even calibrate a delay loop for counts per second, except as a minimum delay potentially sleeping a lot longer at low clock speeds before ramping up. Nov 19 '18 at 22:43
  • Ancient computers had a power consumption that was much less dependent on workload. Modern CPUs need to dynamically power down different parts of the chip as much as possible to not melt (e.g. power down parts of the FPU or SIMD execution units while only integer code is running, or at least gate the clock signal to parts of the chip that don't need to be switching). And entering a low-power sleep state when idle (instead of spinning in an infinite loop waiting for timer interrupts) is also more recent than the ancient computers you mention. Nov 19 '18 at 22:46
  • For more about CPU history, see Modern Microprocessors A 90-Minute Guide! - lighterra.com/papers/modernmicroprocessors. Nov 19 '18 at 22:47

the oldest trick in the book:

read && echo "This is a test"

Just hit Enter and it'll continue!

  • This wont if the process needs to be run interaction free or in the background right?
    – ss_iwe
    Nov 19 '18 at 11:30
  • Correct: But that was not one of the OP's requirements as per the original question, so still a valid answer... ;-) >:-)
    – Fabby
    Nov 20 '18 at 11:30
  • 1
    OP specifically gives an example (with sleep) and asks for an equivalent alternative without. So read doesn't parse, sorry. ;)
    – AnoE
    Nov 20 '18 at 12:58
  • @AnoE Stéphane's answer is of course the best, mine is just the oldest --- press «enter» to continue --- ;-)
    – Fabby
    Nov 20 '18 at 18:00

There is no built-in, that does the same as sleep (unless sleep is built-in). However there are some other commands that will wait.

A few include.

  • at and cron: used to schedule tasks at a specific time.

  • inotifywait: used to wait for a file, or files to be modified/removed/added/etc

  • Thanks for this. Could you provide an example for performing a scheduled task (10 seconds from now) with at?
    – user321697
    Nov 19 '18 at 11:23
  • 1
    an edit and an upvote! ;-)
    – Fabby
    Nov 19 '18 at 11:23
  • cron store tasks in crontab, right? Where does at store the scheduled data?
    – user321697
    Nov 19 '18 at 11:25
  • @user321697 Already answered here
    – Fabby
    Nov 19 '18 at 11:26
  • Sorry for reverting back your edit to the Q: you changed the OPs question's main purpose which would invalidate the simplest answer of all... ¯\_(ツ)_/¯
    – Fabby
    Nov 19 '18 at 11:38

A classic from the Land of Windows and Batches:

ping -c 11 localhost >/dev/null && echo "This is a test"
  • Firewall or name system misconfiguration might introduce a significant additional delay tough.
    – spectras
    Nov 20 '18 at 12:21
  • 1 ... @spectras
    – AnoE
    Nov 20 '18 at 12:59
  • 1
    Thankfully no longer needed, as Windows now supports sleep natively.
    – Baldrickk
    Nov 20 '18 at 13:26
  • 1
    @AnoE> solves the name system part, not the firewall part. Though not common, it can be configured to silently drop pings on local interface. That will cause ping to wait much longer.
    – spectras
    Nov 21 '18 at 1:42
  • +1 for the "fond" memories
    – A C
    Nov 21 '18 at 6:26

If you want to interactively wait for a new line in a file, then

tail -f

Waiting for a change on a filesystem? Then use e.g.

inotify / inoticoming

And there are other options, depending on what you mean with "wait".

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.