In Java it is possible to create a random UUID:
UUID uuid = UUID.randomUUID();
How to do this in Bash?
Server Fault is a question and answer site for system and network administrators. It only takes a minute to sign up.
Sign up to join this communityIn Java it is possible to create a random UUID:
UUID uuid = UUID.randomUUID();
How to do this in Bash?
See the uuidgen
program which is part of the e2fsprogs package.
According to this, libuuid
is now part of util-linux and the inclusion in e2fsprogs is being phased out. However, on new Ubuntu systems, uuidgen
is now in the uuid-runtime
package.
To create a uuid and save it in a variable:
uuid=$(uuidgen)
On my Ubuntu system, the alpha characters are output as lower case and on my OS X system, they are output as upper case (thanks to David for pointing this out in a comment).
To switch to all upper case (after generating it as above):
uuid=${uuid^^}
To switch to all lower case:
uuid=${uuid,,}
If, for example, you have two UUIDs and you want to compare them in Bash, ignoring their case, you can do a tolower()
style comparison like this:
if [[ ${uuid1,,} == ${uuid2,,} ]]
uuid-runtime
package for no apparent reason... +1 to you)
Jan 16, 2010 at 14:05
echo -e 'f\nF' | grep '[[:xdigit:]]'
outputs both lines). If it does matter for you and you have Bash 4, you can do this to make it lower case: uuid=$(uuidgen); uuid=${uuid,,}
or this to make it upper case: uuid=$(uuidgen); uuid=${uuid^^}
or something along these lines to do a tolower()
style test: if [[ ${uuid1,,} == ${uuid2,,} ]]
Oct 14, 2015 at 19:30
To add variety without adding external dependencies, on Linux you can do:
UUID=$(cat /proc/sys/kernel/random/uuid)
To propagate bad practices, on FreeBSD, under the linux compatibility layer (linuxulator?),
UUID=$(cat /compat/linux/proc/sys/kernel/random/uuid)
References:
Just for the sake of completeness... There's also a UUID generator installed with the dbus
package on Debian. I missed it looking around earlier. It's probably the same algorithm as the e2fsprogs package, but it doesn't add the dashes, so it might be a little cleaner for you:
$ uuidgen
387ee6b9-520d-4c51-a9e4-6eb2ef15887d
$ dbus-uuidgen
d17b671f98fced5649a856a54b51c9e6
Grawity adds a safety tip: "DBus UUIDs are not related to or compatible with RFC 4122. Besides, dbus-uuidgen always uses the Unix timestamp as the last 4 bytes. So they might be unsuitable for some uses." (Thanks, Grawity, I should've spotted that in the manpage.)
dbus-uuidgen
always uses the Unix timestamp as the last 4 bytes. So they might be unsuitable for some uses.
Jan 16, 2010 at 15:08
If you do not want to depend on other executables, or you cannot use them, here is the pure bash version from here:
# Generate a pseudo UUID
uuid()
{
local N B T
for (( N=0; N < 16; ++N ))
do
B=$(( $RANDOM%255 ))
if (( N == 6 ))
then
printf '4%x' $(( B%15 ))
elif (( N == 8 ))
then
local C='89ab'
printf '%c%x' ${C:$(( $RANDOM%${#C} )):1} $(( B%15 ))
else
printf '%02x' $B
fi
for T in 3 5 7 9
do
if (( T == N ))
then
printf '-'
break
fi
done
done
echo
}
[ "$0" == "$BASH_SOURCE" ] && uuid
T
variable can be eliminated and the for T
loop can be changed to: case $N in 3 | 5 | 7 | 9) printf '-';; esac
(broken out on separate lines if preferred).
May 22, 2014 at 14:08
case
to eliminate the if
statements as well as the inner for
statement. It makes the code much neater. Note that both B%15
should be B%16
and B%255
should be B%256
.
May 22, 2014 at 17:47
source <(curl url)
or whatever
I have found this script "one-liner" useful where uuidgen is not available. This also bypasses any neccessity to install external modules for Perl or Python.
od -x /dev/urandom | head -1 | awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}'
Tested on SnowLeopard, Red Hat Valhalla, Solaris 9 4/04 and newer successfully. I am curious if this is prone to non-uniqueness, but I have not been 'bit'ten in the last 10 years. Of course, head -1
could be replaced with head -_other-value_ | tail -1
too.
To explain,
/dev/random
and /dev/urandom
are kernel random generators.
od
(octal dump) has a hex output switch (-x) producing 16 bytes per line.
head
-n [| tail -1] (where n>0) extracts just one line of the previous output.
awk
sets the OutputFieldSeparator to be a hyphen everywhere a comma occurs in the print statement. By specifying fields 2-9 independently, we control the hyphens and strip off the index/offset counter that 'od' prefixes each line of output with.
The result is a pattern of 8-4-4-4-12
lower case characters a-f0-9
.
993bb8d7-323d-b5ee-db78-f976a59d8284
od -x /dev/urandom | head -1 | awk '{OFS="-"; srand($6); sub(/./,"4",$5); sub(/./,substr("89ab",rand()*4,1),$6); print $2$3,$4,$5,$6,$7$8$9}'
Sep 29, 2018 at 17:33
Just so python doesn't feel left out:
python -c 'import uuid; print uuid.uuid1()'
2d96768e-02b3-11df-bec2-001e68b9d147
To use it in the shell:
myvar=$(python -c 'import uuid; print uuid.uuid1()')
See the Python Documentation UUID for the kinds of UUIDS that can be generated.
To generate a systemd machine-id compatible file on a non-systemd machine, you could use python to do it this way:
python -c 'import re; import uuid; print re.sub("-","",str(uuid.uuid4()))' \
> /etc/machine-id
Perl provides a UUID library based on the e2fsprogs
package. On my Debian system it's the libuuid-perl
package. Here's an example one-liner; see man uuid
for more:
$ perl -e 'use UUID; UUID::generate($uuid); UUID::unparse($uuid, $string); print "my new UUID is $string \n";'
my new UUID is 3079e9ce-41d4-4cf3-9f90-d12f8bb752e4
This would be trivial to add to a shellscript with backticks or $()
notation:
#!/bin/bash
# ...do some stuff
$myvar = $(perl -e 'use UUID; UUID::generate($uuid); UUID::unparse($uuid, $string); print "$string";')
# ...do some more stuff
apt-get install uuid
Worked for me, then i did run uuid
I wrote a little Bash function using Python to generate an arbitrary number of UUIDs in bulk:
# uuid [count]
#
# Generate type 4 (random) UUID, or [count] type 4 UUIDs.
function uuid()
{
local count=1
if [[ ! -z "$1" ]]; then
if [[ "$1" =~ [^0-9] ]]; then
echo "Usage: $FUNCNAME [count]" >&2
return 1
fi
count="$1"
fi
python -c 'import uuid; print("\n".join([str(uuid.uuid4()).upper() for x in range('"$count"')]))'
}
If you prefer lowercase, change:
python -c 'import uuid; print("\n".join([str(uuid.uuid4()).upper() for x in range('"$count"')]))'
To:
python -c 'import uuid; print("\n".join([str(uuid.uuid4()) for x in range('"$count"')]))'
Please look at the OSSP UUID library (http://www.ossp.org/pkg/lib/uuid/), and consider installing it. Some projects offer it as an option (e.g. PostgreSQL). It properly handles version 3 and version 5 UUIDs, which was beyond what my installed (e.g. e2fsprogs) library could handle. Fortunately, openSUSE has it in one of the main repos. Getting a version to work w/ Windows (e.g. Cygwin) or MySQL has been a flail. Looks like it is time to switch to Linux/PostgreSQL/Python (and I so loved the SQLyog GUI to MySQL/MariaDB) since I really need v3 and v5 UUIDs.
-v3 ns:URL custom-data
seeding mechanism.
Oct 6, 2015 at 18:09
I'm sure some will arrive here, and are just looking for an easy way to generate a unique ID for use in their scripts, and it doesn't need to be a true UUID.
If so, you can just do the following, which will generated a id that's unique down to the second - so if you run this multiple times within a second, you'll still get the same result.
MYID="U$(date +%s)"
echo $MYID
will generate ids like the following based off the current system time:
U1454423662
NOTE: If you're on Linux, or have Coreutils installed on a mac, then you can use the following to generate a unique id to the nanosecond:
MYID="U$(date +%s%N)"
echo $MYID
or if you prefer a python based solution down to the nanosecond, which should work almost everywhere, run:
MYUID=U$(python -c'import time; print repr(time.time())')
echo $MYUID
mktemp -u
as in MYID="$(mktemp -u)"
. If you can afford to have empty temp files laying around until reboot, drop the -u
: MYID="$(mktemp)"
Aug 21, 2016 at 14:08
This thread, with it's varied examples, was really useful to me. I frequently need uuid functions from a number of different environments. And while I love the pure bash examples, it's sometimes more convenient to use a library from a different language.
So just for thoroughness, ruby (1.9.3+) has the built-in SecureRandom module containing a number of useful hash and id functions. From the bash cli, you can do this.
ruby -r securerandom -e 'puts SecureRandom.uuid'
ran=`od -X -A n /dev/random | head -1 | cut -c3-38`
correlation_id=`echo ${ran} | cut -c1-8`-`echo ${ran} | cut -c10-13`-`echo ${ran} | cut -c14-17`-`echo ${ran} | cut -c19-22`-`echo ${ran} | cut -c23-26``echo ${ran} | cut -c28-35`
od -X -A n /dev/random | head -1 | cut -c3-38
gives you this below echo $x 4151540a 1f7d0bef 8a0725fb d26183a3 uuid=echo ${x} | cut -c1-8
-echo ${x} | cut -c10-13
-echo ${x} | cut -c14-17
-echo ${x} | cut -c19-22
-echo ${x} | cut -c23-26``echo ${x} | cut -c28-35
echo $uuid 4151540a-1f7d-0bef-8a07-25fbd26183a3
If you are using Java 10.
$ jshell
jshell> import java.util.*
jshell> String id = UUID.randomUUID().toString();
jshell
can be used in bash scripting, and not as an interactive command. That is very clear in the original post.
echo "System.out.println(java.util.UUID.randomUUID().toString())" | /Library/Java/JavaVirtualMachines/openjdk-11.0.1.jdk/Contents/Home/bin/jshell -s | grep -v ">"
But it is a lot more long winded than uuidgen
.