Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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?

share|improve this question

2 Answers 2

up vote 4 down vote accepted

Short 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.

share|improve this answer
    
Thanks for taking the time to explain this to me –  user2284355 Mar 11 at 16:10

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.