I have the following line to generate a random number:
head -c 3 /dev/urandom | hexdump | sed -e 's/[0 a-z]//g' | head -c 1
This works fine but sometimes (very few) it returns a new line. Does anyone know why this might be?
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 communityShort answer: Your three random bytes match [0a-f]+ in hex.
Long answer: The hexdump
command in your pipe returns an address offset, followed by a space and the hex representation of the three bytes you receive from head -c 3 /dev/urandom
. The address offset in the first line is always "0000000", so it gets discarded by the sed
filter, as well as the space after it. So the only relevant thing fed to the sed
command in the first line is the hex representation of the three urandom
bytes. But it will happen (randomly ;-)) that the hex representation of all three bytes will consist of the number 0 and the characters a
through f
, only. So your sed
filter will return nothing for the first line, which leaves a single newline. The head -c 1
at the end of the pipe will filter out the next line from hexdump
, so you will see nothing.
An example with not so random numbers:
# First three bytes with values 4, 5 and 6 octal.
$ echo -n $'\004\005\006' | hexdump
0000000 0504 0006
0000004
# Because of little endianess, we get the 5 back after the sed and head filters
$ echo -n $'\004\005\006' | hexdump | sed -e 's/[0 a-z]//g' | head -c 1
5
# Now with FF bytes (be aware that it is octal notation),
# only 'f' and '0' and space are left:
$ echo -n $'\377\377\377' | hexdump
0000000 ffff 00ff
0000004
# Now filtering this through sed gives nothing back
$ echo -n $'\377\377\377' | hexdump | sed -e 's/[0 a-z]//g' | head -c 1
$
You should use $RANDOM
, as @Iain wrote.
I've no idea why your command is generating a new line but it seems very convoluted. Have you tried working with the bash builtin $RANDOM
?
echo $(( $RANDOM % 9 ))
for example.
There's also lots of apparently less convoluted ways to do it here on Stack Overflow.