Use the sleep command.

Example:

sleep .5 # Waits 0.5 second.
sleep 5  # Waits 5 seconds.
sleep 5s # Waits 5 seconds.
sleep 5m # Waits 5 minutes.
sleep 5h # Waits 5 hours.
sleep 5d # Waits 5 days.

One can also employ decimals when specifying a time unit; e.g. sleep 1.5s

Answer from RydallCooper on Stack Overflow
🌐
nixCraft
cyberciti.biz › nixcraft › howto › linux › python sleep(): add delay in a seconds to suspend execution of a script
Python sleep(): Add Delay In A Seconds To Suspend Execution Of A Script - nixCraft
January 9, 2021 - Finally, add 1 second delay in a script using sleep(1) (line #15). Continue this procedure till user interrupts. The signal.signal() function allows defining custom handlers to be executed when a signal is received. #!/usr/bin/python # The following will run infinity times on screen till user hit CTRL+C # The program will sleep for 1 second before updating date and time again.
🌐
Real Python
realpython.com › python-sleep
Python sleep(): How to Add Time Delays to Your Code – Real Python
August 1, 2023 - The timeit module has several other command line options that you can check out in its documentation. Let’s create something a bit more realistic. A system administrator needs to know when one of their websites goes down. You want to be able to check the website’s status code regularly, but you can’t query the web server constantly or it will affect performance. One way to do this check is to use a Python sleep() system call:
🌐
Python Central
pythoncentral.io › pythons-time-sleep-pause-wait-sleep-stop-your-code
Python's time.sleep() - Pause, Stop, Wait or Sleep your Python Code | Python Central
December 30, 2021 - Essentially, as the name implies, it pauses your Python program. The time.sleep()command is the equivalent to the Bash shell's sleep command.
🌐
Programiz
programiz.com › python-programming › time › sleep
Python sleep() (With Examples)
import time while True: # get current local time as structured data current_time = time.localtime() # format the time in 12-hour clock with AM/PM formatted_time = time.strftime("%I:%M:%S %p", current_time) print(formatted_time) time.sleep(1)
🌐
CodeFatherTech
codefather.tech › home › blog › bash sleep command: a quick guide to use it in your scripts
Bash Sleep Command: A Quick Guide to Use It in Your Scripts
June 27, 2025 - Sleeping for 6 seconds..." sleep 6 else echo "File stage1.complete exists. Stage 1 complete, starting Stage 2..." rm stage1.complete exit fi done · In the second Bash shell script, we have an infinite loop. At every iteration of the script: Check if the file stage1.complete is present. ... If the file exists remove the stage1.complete file and stop the execution using the Bash exit command.
🌐
TecAdmin
tecadmin.net › sleep-delay-in-python
How to Use Sleep in Python Script – TecAdmin
April 26, 2025 - In Python programming function you can use sleep() function available under time module. This will sleep or delay script execution for the defined number of seconds. You can use time.sleep(seconds) as per following. The value passed to sleep() function is in second.
Find elsewhere
🌐
nixCraft
cyberciti.biz › nixcraft › howto › bash shell › linux / unix bash script sleep or delay a specified amount of time
Linux / UNIX Bash Script Sleep or Delay a Specified Amount of Time - nixCraft
May 26, 2023 - ## run commmand1, sleep for 1 minute and finally run command2 ## command1 && sleep 1m && command2 ## sleep in bash for loop ## for i in {1..10} do do_something_here sleep 5s done ## run while loop to display date and hostname on screen ## while [ : ] do clear tput cup 5 5 date tput cup 6 5 echo "Hostname : $(hostname)" sleep 1 done
🌐
Delft Stack
delftstack.com › home › howto › linux › how to use the sleep command in bash
How to Use the sleep Command in Bash | Delft Stack
March 14, 2025 - Python ScipyPythonPython TkinterBatchPowerShellPython PandasNumpyPython FlaskDjangoMatplotlibDockerPlotlySeabornMatlabLinuxGitCCppHTMLJavaScriptjQueryPython PygameTensorFlowTypeScriptAngularReactCSSPHPJavaGoKotlinNode.jsCsharpRustRubyArduinoMySQLMongoDBPostgresSQLiteRVBAScalaRaspberry Pi ... The sleep command in Bash is a simple yet powerful tool that allows you to pause the execution of your scripts or commands for a specified period.
🌐
Python.org
discuss.python.org › python help
Sleep Comand Questin - Python Help - Discussions on Python.org
August 11, 2023 - Hello. 😀 😀 What is the limits of the sleep command? I need a 0.000666666665 delay ) but it does not seem to work. Sometimes it is perfect but most times it all over the page. It not constant.
🌐
Linuxize
linuxize.com › home › linux commands › linux sleep command (pause a bash script)
Linux Sleep Command (Pause a Bash Script) | Linuxize
January 31, 2026 - Then the sleep command pauses the script for 5 seconds. Once the specified time period elapses, the last line prints the current time. ... The following script checks whether a host is online every 5 seconds and notifies you when it becomes ...
🌐
EDUCBA
educba.com › home › software development › software development tutorials › software development basics › bash sleep command
Bash Sleep Command | Complete Guide on Bash Sleep Command
March 29, 2023 - This is a guide to Bash Sleep Command. Here we discuss How does Sleep Command works in Bash and Options, along with codes and outputs.
Address   Unit no. 202, Jay Antariksh Bldg, Makwana Road, Marol, Andheri (East),, 400059, Mumbai
🌐
Linux Tip
linuxscrew.com › home › programming › python › python time.sleep() to pause, sleep, wait or stop a python script
Python time.sleep() to Pause, Sleep, Wait or Stop a Python Script
June 23, 2022 - To show that things were paused for the correct duration, the result of the time.ctime() method was printed before and after time.sleep() time.ctime() will return the current local time when it is run · Computers execute code very, very quickly – If you’re building interactive apps you’ll need to pause every now and then to let the user catch up! Click here for more Python stuff! SHARE: Related Articles · How to use the Bash wait Command (it's Different to sleep) Using PHP sleep() and usleep() to Pause Execution [Examples] Using the 'sleep' Function in Bash Scripts, with Examples ·
🌐
Mimo
mimo.org › glossary › python › time-sleep
Python time sleep: Pausing Code Execution in Python
A countdown timer can be implemented using time.sleep(). This might be useful in a command-line interface or any scenario where you want to display a countdown.
🌐
DigitalOcean
digitalocean.com › community › tutorials › python-time-sleep
Python time.sleep(): How to Pause Execution in Python Scripts | DigitalOcean
January 27, 2026 - I am trying to create suspense" for i in message: print(i) time.sleep(0.3) When you run this script, each character appears on the screen after a short pause, creating a gradual output effect. This technique is sometimes used in command-line applications, demonstrations, or simple animations where controlled output timing improves readability or presentation.
Top answer
1 of 16
136

As mentioned by Outlaw Programmer, I think the solution is just to sleep for the correct number of seconds.

To do this in bash, do the following:

current_epoch=$(date +%s)
target_epoch=$(date -d '01/01/2010 12:00' +%s)

sleep_seconds=$(( $target_epoch - $current_epoch ))

sleep $sleep_seconds

To add precision down to nanoseconds (effectively more around milliseconds) use e.g. this syntax:

current_epoch=$(date +%s.%N)
target_epoch=$(date -d "20:25:00.12345" +%s.%N)

sleep_seconds=$(echo "$target_epoch - $current_epoch"|bc)

sleep $sleep_seconds

Note that macOS / OS X does not support precision below seconds, you would need to use coreutils from brew instead → see these instructions

2 of 16
67

Sample edited: Wed Apr 22 2020, something between 10:30 and 10h:55
(Important for reading samples)

0. Preamble

In this not so short answer, I will present

  1. Avoiding useless forks!
  2. POSIX shell compatible
    1. High precision (nanosec)
    2. Reaching next time
  3. Pure bash way, no fork!!
    1. As a function
  4. HiRes time with bash
    1. sleep until next period
    2. Old method using /proc/timer_list under GNU/Linux
    3. Little test function
  5. What if host do hibernate during sleep command?
    1. Test on my laptop
  6. Care to not mix $EPOCHSECOND and $EPOCHREALTIME
  7. About sleep <float> vs read -t <float> _
    1. Some tests (on my raspberry)
    2. Using bash'sleep loadable module

To avoid consecutive forks, this method use GNU date -f which is not POSIX and don't work under MacOS! If under Mac, goto my pure bash function or install GNU date!

1. Simple starting sample POSIX shell compatible

In order to reduce forks, instead of running date two times, I prefer to use this:

sleep $(( $( printf '%s\nnow\n' "tomorrow 21:30" | date -f - +%s- ) 0 ))

where tomorrow 21:30 could be replaced by any kind of date format recognized by date command, ( in the future of course ;) .

if read -rp "Sleep until: "  targetTime ;then
    sleep $(( $( printf '%s\nnow\n' "$targetTime" | date -f - +%s- ) 0 ))
fi

1.1. With high precision (nanosec)

Nearly same:

target='07:00 tomorrow'
sleep $(echo s$( printf '%s\nnow\n' "$target"| date -f - +'t=%s.%N;')st-t | bc)

Verbose:

target='07:00 tomorrow'
echo sleep $(echo s$( printf '%s\nnow\n' "$target" | date -f - +'t=%s.%N;')st-t|
    bc ) | tee /dev/tty | sh

1.2. Reaching next time

For reaching next HH:MM meaning today if possible, tomorrow if too late:

sleep $(( ( $( printf 'tomorrow %s\nnow\n' 21:30 | date -f - +%s-) 0 ) % 86400 ))

Under bash, ksh and some other modern shells, you could write:

sleep $(( ( $( date -f - +%s- <<<"21:30"$' tomorrow\nnow' ) 0 ) % 86400 ))

2. Pure bash way, no fork!!

Tested under MacOS!

Under bash, you could use printf -v now '%(%s)T' -1 for storing current UNIXEPOCH in variable $now.

2.1. As a function

I wrote one two little functions: sleepUntil and sleepUntilHires

 Syntax:
 sleepUntil [-q] <HH[:MM[:SS]]> [more days]
     -q Quiet: don't print sleep computed argument
     HH          Hours (minimal required argument)
     MM          Minutes (00 if not set)
     SS          Seconds (00 if not set)
     more days   multiplied by 86400 (0 by default)

To sleep until HH:MM whithout using date or any other fork, I've build a little bash function. Here it is:

sleepUntil() { # args: [-q] <HH[:MM[:SS]]> [more days]
    local slp tzoff now quiet=false
    [ "$1" = "-q" ] && shift && quiet=true
    local -a hms=(${1//:/ })
    printf -v now '%(%s)T' -1
    printf -v tzoff '%(%z)T' $now
    tzoff=$((0${tzoff:0:1}(3600*10#${tzoff:1:2}+60*10#${tzoff: -2})))
    slp=$(((( 86400 + ( now - now%86400 ) +
                10#$hms*3600+10#${hms[1]:-0}*60+10#${hms[2]:-0} -
                tzoff - now
            ) % 86400 ) + 10#${2:-0} * 86400
          ))
    $quiet || printf 'sleep %ss, -> %(%c)T\n' $slp $((now+slp))
    read -t $slp _
}

Then:

sleepUntil 10:37 ; date +"Now, it is: %T"
sleep 49s, -> Wed Apr 22 10:37:00 2020
Now, it is: 10:37:00

sleepUntil -q 10:37:44 ; date +"Now, it is: %T"
Now, it is: 10:37:44

sleepUntil 10:50 1 ; date +"Now, it is: %T"
sleep 86675s, -> Thu Apr 23 10:50:00 2020
^C

If target is before this will sleep until tomorrow:

sleepUntil 10:30 ; date +"Now, it is: %T"
sleep 85417s, -> Thu Apr 23 10:30:00 2020
^C

sleepUntil 10:30 1 ; date +"Now, it is: %T"
sleep 171825s, -> Fri Apr 24 10:30:00 2020
^C

3. HiRes time with bash

Recent bash, from version 5.0 add new $EPOCHREALTIME variable with microseconds.

From this there is a sleepUntilHires function:

sleepUntilHires() { # args: [-q] <HH[:MM[:SS[.xxx]]]> [more days]
    local slp tzoff now quiet=false musec musleep tmu
    [ "$1" = "-q" ] && shift && quiet=true
    local -a hms
    IFS=: read -a hms <<<${1}
    printf -v tmu %.06f ${hms[2]:-0}
    printf -v hms[2] %.0f ${tmu%.*}
    tmu=${tmu#*.}
    printf -v now '%(%s)T' -1
    IFS=. read now musec <<<$EPOCHREALTIME
    musleep=$((2000000+10#$tmu-10#$musec))
    printf -v tzoff '%(%z)T\n' $now
    tzoff=$((0${tzoff:0:1}(3600*10#${tzoff:1:2}+60*10#${tzoff:3:2})))
    slp=$(((( 86400 + ( now - now%86400 ) +
                10#$hms*3600+10#0${hms[1]:-0}*60+10#${hms[2]:-0} -
                tzoff - now - 1
            ) % 86400 ) + 10#${2:-0} * 86400
          )).${musleep:1}
    $quiet ||
        printf 'sleep %ss, -> %(%c)T.%s\n' $slp $((now+${slp%.*}+1)) $tmu
    read -t $slp _
}

Please note: this use read -t wich is built-in, instead of sleep. Unfortunely, this won't work when running in background, without real TTY. Feel free to replace read -t by sleep if you plan to run this in background scripts... (But for background process, consider using cron and/or at instead of all this)

3.1. HiRes sleep until next period

About RonJohn's comment, if the goal is to start every 15 minutes, sleep command could become:

sleepUntilNext() { # args: [-q] <float period in seconds>
    local slp sec mus quiet=0 res=0 chr
    [[ $1 == -q ]] && quiet=1 && shift
    printf -v slp %.6f $1
    slp=00000$(( 10#${slp/.} - ${EPOCHREALTIME/.} % 10#${slp/.} ))
    printf -v slp %.6f ${slp::-6}.${slp: -6}
    ((quiet)) || printf 'Sleep %s...' $slp >&2
    IFS= read -d '' -rsn1 -t $slp chr &&
        printf -v res %d \'"$chr"
    IFS=. read sec mus <<<$EPOCHREALTIME
    ((quiet)) || {
        IFS=. read sec mus <<<$EPOCHREALTIME
        printf '\rDone: %(%a %d %T)T.%s\e[K\n' $sec $mus >&2
    }
    return $res
}

Then for a period of 15':

sleepUntilNext 900
Sleep 662.334231...
Done: Wed 26 16:15:00.000171

for 20':

sleepUntilNext 1200
Sleep 11.509587...
Done: Wed 26 16:20:00.000168

But this accept float values as period:

while sleepUntilNext -q 1.5;do date +%T.%N;done
16:32:49.502416682
16:32:51.001073971
16:32:52.502804292
16:32:54.002940518
16:32:55.503174242

(Replace read -t by sleep or use pseudo FD... see About sleep and/or read -t further)

Skip next paragraph for tests and warning about $ËPOCHSECONDS!

3.2. Older method using /proc/timer_list under GNU/Linux

Avoided to normal user, by recent Kernel!! Do require root user

Under Linux kernel, you will find a variables file named /proc/timer_list where you could read an offset and a now variable, in nanoseconds. So we may compute sleep time to reach the very top desired time.

(I wrote this to generate and track specific events on very big log files, containing thousand line for one second).
mapfile  </proc/timer_list _timer_list
for ((_i=0;_i<${#_timer_list[@]};_i++));do
    [[ ${_timer_list[_i]} =~ ^now ]] && TIMER_LIST_SKIP=$_i
    [[ ${_timer_list[_i]} =~ offset:.*[1-9] ]] && \
    TIMER_LIST_OFFSET=${_timer_list[_i]//[a-z.: ]} && \
     break
done
unset _i _timer_list
readonly TIMER_LIST_OFFSET TIMER_LIST_SKIP

sleepUntilHires() {
    local slp tzoff now quiet=false nsnow nsslp
    [ "$1" = "-q" ] && shift && quiet=true
    local hms=(${1//:/ })
    mapfile -n 1 -s $TIMER_LIST_SKIP nsnow </proc/timer_list
    printf -v now '%(%s)T' -1
    printf -v tzoff '%(%z)T\n' $now
    nsnow=$((${nsnow//[a-z ]}+TIMER_LIST_OFFSET))
    nsslp=$((2000000000-10#${nsnow:${#nsnow}-9}))
    tzoff=$((0${tzoff:0:1}(3600*${tzoff:1:2}+60*${tzoff:3:2})))
    slp=$(( ( 86400 + ( now - now%86400 ) +
            10#$hms*3600+10#${hms[1]}*60+${hms[2]} -
            tzoff - now - 1
        ) % 86400)).${nsslp:1}
    $quiet || printf 'sleep %ss, -> %(%c)T\n' $slp $((now+${slp%.*}+1))
    sleep $slp
}

After defining two read-only variables, TIMER_LIST_OFFSET and TIMER_LIST_SKIP, the function will access very quickly the variable file /proc/timer_list for computing sleep time:

 

3.3. Little test function

Showing near begin and end of every seconds, by sleeping 0,92 between two outputs of same HMS...

tstSleepUntilHires () { 
    local now next last
    printf -v next "%(%H:%M:%S)T" $((${EPOCHREALTIME%.*}+1))
    sleepUntilHires $next
    date -f - +%F-%T.%N < <(echo now;sleep .92;echo now)
    printf -v next "%(%H:%M:%S)T" $((${EPOCHREALTIME%.*}+1))
    sleepUntilHires $next
    date +%F-%T.%N
}

May render something like:

sleep 0.244040s, -> Wed Apr 22 10:34:39 2020.000000
2020-04-22-10:34:39.001685312
2020-04-22-10:34:39.922291769
sleep 0.077012s, -> Wed Apr 22 10:34:40 2020.000000
2020-04-22-10:34:40.004264869
  • At begin of next second,
  • print time, then
  • wait 0.92 seccond, then
  • print time, then
  • compute 0.07 seconds left, to next second
  • sleep 0.07 seconds, then
  • print time.

4. What if host do hibernate during sleep command?

Jan 2023: New chapter about GregD's comment and hibernation

GregD's comment warned about too long sleep if initiated before computer going into deep sleep mode...

For this I've rewrited sleepUntilHires: Of course, they won't wake computer up, but end immediately (max 20 ms) when waked and show time gap.

sleepUntilHires() { # args: [-q] <HH[:MM[:SS[.xxx]]]> [more days]
    local slp tzoff now quiet=false musec musleep tmu start=${EPOCHREALTIME} tgt
    [[ $_dummySleepFd ]] && [[ -e /dev/fd/$_dummySleepFd ]] ||
        exec {_dummySleepFd}<> <(:)
    [ "$1" = "-q" ] && shift && quiet=true
    local -a hms; IFS=: read -a hms <<<${1}
    printf -v tmu %.06f ${hms[2]:-0}
    printf -v hms[2] %.0f ${tmu%.*}
    tmu=${tmu#*.}; printf -v now '%(%s)T' -1
    IFS=. read now musec <<<$start
    musleep=$((2000000+10#$tmu-10#$musec))
    printf -v tzoff '%(%z)T\n' $now
    tzoff=$((0${tzoff:0:1}(3600*10#${tzoff:1:2}+60*10#${tzoff:3:2})))
    slp=$(((( 86400 + ( now - now%86400 ) +
                10#$hms*3600+10#0${hms[1]:-0}*60+10#${hms[2]:-0} -
                tzoff - now - 1
            ) % 86400 ) + 10#${2:-0} * 86400
          )).${musleep:1}
    tgt=$((${start/.}+10#${slp/.}))
    printf -v tmu  '%(%c)T.%s' $(((${start/.}+10#${slp/.})/1000000)) $tmu
    while ((slp=tgt-${EPOCHREALTIME/.},slp>0)) ;do
        slp=00000$slp
        printf -v slp %.6f ${slp::-6}.${slp: -6}
        $quiet || printf '\rsleep %ss, -> %s ...' "$slp" "$tmu"
        if (( 10#${slp/.} > 20000));then      # If left more than 20 ms
            read -u $_dummySleepFd -t .02 _   # then sleep 20 ms
        else read -u $_dummySleepFd -t $slp _ # else sleep left time
        fi 
    done
    if ! $quiet;then  now=00000$((${EPOCHREALTIME/.}-tgt))
        printf '\nScript done %.6f seconds late.\n' ${now::-6}.${now: -6}
    fi        
}

4.1. Test on my laptop

Well I have to start my laptop now...

sleepUntilHires 15:13:18.1234
sleep 0.002148s, -> lun 16 jan 2023 15:13:18 CET.123400 ...
Script done 0.000746 seconds late.

That was a normal run. Now I will put my laptop in hibernation:

sleepUntilHires 15:15:18.1234
sleep 86.256328s, -> lun 16 jan 2023 15:15:18 CET.123400 ...
Script done 111.469551 seconds late.

Then sleep finish immediately when waked up, and show his final gap.

5. Care to not mix $EPOCHSECOND and $EPOCHREALTIME!

Read my warning about difference between $EPOCHSECOND and $EPOCHREALTIME

This function use $EPOCHREALTIME so don't use $EPOCHSECOND for establishing next second:

Sample issue: Trying to print time next rounded by 2 seconds:

for i in 1 2;do
    printf -v nextEvenSecond "%(%T)T" $(((EPOCHSECONDS/2)*2+2))
    echo $nextEvenSecond
    sleepUntilHires $nextEvenSecond
    IFS=. read now musec <<<$EPOCHREALTIME
    printf "%(%c)T.%s\n" $now $musec
done

May produce:

11:44:32
sleep 1.485212s, -> Wed Nov  9 11:44:32 2022.000000
Wed Nov  9 11:44:32 2022.000311
11:44:32
sleep 86399.999143s, -> Thu Nov 10 11:44:32 2022.000000

You are going to wait 1 day instead of 2 seconds!!!

You have to use $EPOCHREALTIME:

    printf -v nextEvenSecond "%(%T)T" $(((${EPOCHREALTIME%.*}/2)*2+2))
11:48:12
sleep 0.300672s, -> Wed Nov  9 11:48:12 2022.000000
Wed Nov  9 11:48:12 2022.000345
11:48:14
sleep 1.998397s, -> Wed Nov  9 11:48:14 2022.000000
Wed Nov  9 11:48:14 2022.000536
11:48:16
sleep 1.998916s, -> Wed Nov  9 11:48:16 2022.000000
Wed Nov  9 11:48:16 2022.000325

6. About sleep and/or read -t

In this functions, I use read -t (timeout) instead of sleep, for two reasons:

  • this permit user to interrupt sleep by hitting Return key.
    (Variant: IFS= read -sn 1 -t $slp _, to permit user to interrupt by hitting Any key).
  • sleep implie a call (fork) to /bin/sleep as it's not a buitin.

For avoiding user interrupt by keyboard interaction aka for running this non interactively, you could

  • create a pseudo tty (file descriptor) for redirecting read's input at begin of sleepUntil.source script:
   exec {_dummySleepFd}<> <(:)

then replace

   read -t $slp _

by

   read -u $_dummySleepFd -t $slp _
  • Load sleep loadable builtin if your bash implementation permit this (see sudo apt install bash-builtins):
   enable -f sleep sleep

if your $BASH_LOADABLES_PATH is set, else:

   enable -f /usr/lib/bash/sleep sleep

to unload/disable:

   enable -d sleep

6.1. some tests (on my raspberry):

Command sleep 0.01 runned between two print of UNIXEPOCH in microseconds could print something greater (or equal) to 10000 microseconds...

By using read -t instead of sleep:

exec {_dummySleepFd}<> <(:)
s=${EPOCHREALTIME/.};read -u $_dummySleepFd -t .01;echo $((${EPOCHREALTIME/.}-s))
10975

s=${EPOCHREALTIME/.};read -u $_dummySleepFd -t .01;echo $((${EPOCHREALTIME/.}-s))
10977

Near 1000 microseconds -> 1 milliseconds late.

With /bin/sleep:

s=${EPOCHREALTIME/.};sleep .01;echo $((${EPOCHREALTIME/.}-s))
60676

s=${EPOCHREALTIME/.};sleep .01;echo $((${EPOCHREALTIME/.}-s))
47910

s=${EPOCHREALTIME/.};sleep .01;echo $((${EPOCHREALTIME/.}-s))
44585

First time run, /bin/sleep was loaded from filesystem. this is longer 60676 - 10000 = 50676 -> 50 milliseconds!!

But anyway, even in cache memory, running a fork to sleep is ressource killer...

6.2. Using bash'sleep loadable module:

enable -f /usr/lib/bash/sleep sleep
s=${EPOCHREALTIME/.};sleep .01;echo $((${EPOCHREALTIME/.}-s))
10803

s=${EPOCHREALTIME/.};sleep .01;echo $((${EPOCHREALTIME/.}-s))
10760

Seem maybe a little better than using read -u $_dummySleepFd -t ... and still more readable in bash scripts.