Universally Unique Identifiers (UUIDs) are essential for generating distinct identifiers in distributed systems. While many languages provide built-in UUID generation, Bash requires external tools or creative solutions.
The simplest approach on Unix-like systems:
# Generate version 4 random UUID
uuid=$(uuidgen)
echo "Generated UUID: $uuid"
# Generate version 1 time-based UUID
uuid=$(uuidgen -t)
echo "Time-based UUID: $uuid"
On modern Linux systems:
uuid=$(cat /proc/sys/kernel/random/uuid)
echo "Kernel-generated UUID: $uuid"
When other tools aren't available:
uuid=$(openssl rand -hex 16 | awk '{print substr($0,1,8)"-"substr($0,9,4)"-"substr($0,13,4)"-"substr($0,17,4)"-"substr($0,21,12)}')
echo "OpenSSL-generated UUID: $uuid"
For environments with no external tools:
generate_uuid() {
local N B C='89ab'
for (( N=0; N < 16; ++N ))
do
B=$(( RANDOM%256 ))
case $N in
6) printf '4%x' $(( B%16 )) ;;
8) printf '%c%x' ${C:$(( RANDOM%${#C} )):1} $(( B%16 )) ;;
3 | 5 | 7 | 9) printf '%02x-' $B ;;
*) printf '%02x' $B ;;
esac
done
echo
}
uuid=$(generate_uuid)
echo "Pure Bash UUID: $uuid"
To verify your UUIDs conform to RFC 4122:
validate_uuid() {
local uuid_pattern='^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$'
if [[ $1 =~ $uuid_pattern ]]; then
echo "Valid UUID: $1"
else
echo "Invalid UUID format" >&2
return 1
fi
}
Benchmarking different methods (on Ubuntu 20.04):
# uuidgen
time for i in {1..1000}; do uuidgen >/dev/null; done
# real 0m0.798s
# /proc method
time for i in {1..1000}; do cat /proc/sys/kernel/random/uuid >/dev/null; done
# real 0m0.112s
# OpenSSL
time for i in {1..1000}; do openssl rand -hex 16 >/dev/null; done
# real 0m1.342s
# Pure Bash
time for i in {1..1000}; do generate_uuid >/dev/null; done
# real 0m3.876s
Practical applications for UUIDs in Bash:
# Temporary file with UUID
temp_file="/tmp/$(uuidgen).log"
echo "Data" > "$temp_file"
# Database record identification
db_insert() {
local id=$(uuidgen)
sqlite3 db.sqlite "INSERT INTO records VALUES('$id', '$1')"
}
# Distributed locking
lock_file="/var/lock/$(uuidgen)"
if mkdir "$lock_file"; then
# Critical section
rm -rf "$lock_file"
else
echo "Process already running"
fi
UUIDs (Universally Unique Identifiers) are 128-bit numbers used to uniquely identify information in computer systems. While Java provides UUID.randomUUID()
, Bash requires different approaches.
The simplest way to generate a UUID in Bash is using the uuidgen
utility, typically pre-installed on most Linux distributions:
# Generate a random UUID
uuid=$(uuidgen)
echo $uuid
For systems without uuidgen, you can read from the kernel's random UUID generator:
# Read UUID from kernel
uuid=$(cat /proc/sys/kernel/random/uuid)
echo $uuid
If you have Python installed, this provides a cross-platform solution:
# Generate UUID with Python
uuid=$(python -c 'import uuid; print(uuid.uuid4())')
echo $uuid
For environments with limited tools, here's a Bash function that generates UUIDv4:
generate_uuid() {
local N B C='89ab'
for (( N=0; N < 16; ++N )); do
B=$(( $RANDOM%256 ))
case $N in
6) printf '4%x' $(( B%16 )) ;;
8) printf '%c%x' ${C:$RANDOM%${#C}:1} $(( B%16 )) ;;
3 | 5 | 7 | 9) printf '%02x-' $B ;;
*) printf '%02x' $B ;;
esac
done
echo
}
To verify your UUIDs are properly formatted:
# Check UUID format
if [[ $uuid =~ ^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$ ]]; then
echo "Valid UUIDv4"
else
echo "Invalid UUID"
fi
When generating many UUIDs in scripts:
uuidgen
is fastest (100k in ~2.5s)- Kernel method is slightly slower (100k in ~3s)
- Python adds overhead (100k in ~12s)
- Pure Bash is slowest (100k in ~45s)
Common applications include:
# Temporary file with UUID
temp_file="/tmp/$(uuidgen).tmp"
touch "$temp_file"
# Unique directory creation
mkdir "data-$(uuidgen | cut -c1-8)"