While the standard sleep
command works well for whole seconds, many modern scripting scenarios require finer-grained timing:
# Standard second-based sleep
sleep 1 # Wait one second
On most modern Unix-like systems (Linux, macOS), the sleep command accepts fractional seconds:
# Sub-second sleep examples
sleep 0.1 # 100ms delay
sleep 0.01 # 10ms delay
sleep 0.001 # 1ms delay (theoretical minimum)
Older Unix systems (Solaris, some BSD variants) typically reject fractional arguments. Here are alternative approaches:
Using usleep (Microsecond Sleep)
# Available on many systems (not POSIX standard)
usleep 100000 # 100ms = 100,000 microseconds
Perl One-Liner
perl -e 'select(undef,undef,undef,0.1)' # 100ms delay
Python Alternative
python -c 'import time;time.sleep(0.1)' # 100ms delay
This function automatically selects the best available method:
millisleep() {
# Try fractional sleep first
sleep 0.001 2>/dev/null && return
# Fallback to usleep if available
if command -v usleep >/dev/null; then
usleep $(($1 * 1000))
return
fi
# Final fallback to perl
perl -e 'select(undef,undef,undef,'${1}'/1000)'
}
# Usage:
millisleep 100 # Sleep for 100 milliseconds
Important notes about sub-second sleep precision:
- Actual precision depends on system scheduler (typically ~1-10ms)
- Very short sleeps (under 10ms) may be unreliable
- For high-precision timing, consider specialized tools or languages
When implementing frequent short delays:
- Forking external commands (perl/python) has overhead
- For tight loops, consider rewriting in a single language
- Test actual timing with
time
command
While the sleep
command is universally available in Unix-like systems, its behavior varies significantly when dealing with fractional seconds. Linux and macOS systems typically accept decimal values:
# Works on Linux/macOS
sleep 0.1 # 100ms delay
sleep 0.01 # 10ms delay
However, traditional Unix systems like Solaris and some BSD variants reject this syntax, considering it invalid.
Here are several cross-platform solutions that work across different Unix-like systems:
1. Using Perl or Python
When you have scripting languages available, they provide precise timing:
# Perl solution
perl -e 'select(undef,undef,undef,0.1);'
# Python solution
python -c 'import time;time.sleep(0.1)'
2. Using usleep (Microsecond Sleep)
Many systems provide usleep
which takes microseconds:
usleep 100000 # 100ms (100,000 microseconds)
Note: usleep
is deprecated in newer systems in favor of nanosleep
, but remains widely available.
3. Using read with timeout
A pure shell solution using bash/ksh built-ins:
# Bash/Ksh solution
read -t 0.1 < /dev/null
For Solaris specifically, you might need to use:
# Solaris solution (if /usr/bin/sleep doesn't support decimals)
/usr/xpg4/bin/sleep 0.1
Here's how different methods compare in terms of accuracy:
# Test script to compare methods
start=$(date +%s.%N)
sleep 0.1
end=$(date +%s.%N)
echo "Native sleep: $(echo "$end - $start" | bc) seconds"
start=$(date +%s.%N)
perl -e 'select(undef,undef,undef,0.1);'
end=$(date +%s.%N)
echo "Perl sleep: $(echo "$end - $start" | bc) seconds"
Consider these factors when selecting an approach:
- System portability requirements
- Available utilities/languages
- Precision needed (millisecond vs microsecond)
- Performance overhead
For most modern systems, the native sleep
with decimal support is preferable when available. For maximum compatibility, the Perl/Python solutions or usleep
are good alternatives.