I’m trying to read some bytes out of /dev/urandom, keep only the ones I can type easily, and trim the result to 30 characters. I can’t figure out how to get the “only 30 characters” behavior when the data is coming from a pipe, though. I tried

cat /dev/urandom | tr -cd 'A-Za-z0-9' | cut -c -30


cut -c -30 /dev/urandom | tr -cd 'A-Za-z0-9' | cut -c -30

but these hang without displaying anything. On the other hand,

cut -c -30 /dev/urandom | tr -cd 'A-Za-z0-9'

outputs data endlessly (although it’s clearly been processed by tr because only the specified characters appear in the output).

In general, how can I read a certain number of characters (or bytes) from a pipe and then close the pipe?


cut will read the input until end-of-file, and cut a part out of each line. With the two first commands, you don't see anything, since tr removes any newlines, and so cut never sees a full line to process. In the last, the tr again removes newlines so you don't see how nicely cut kept the lines to a certain length.

Assuming your head utility supports the -c <characters> option, you could use it to get a fixed number of bytes. If it doesn't, use dd. (dd bs=1 count=NNN < /dev/urandom)

So, this would produce 32 alphanumerics (and a trailing newline):

tr -cd 'A-Za-z0-9' < /dev/urandom | head -c32 ; echo

Though, just out of principle, that's a bit of a waste since the tr tosses away about 3/4 or the raw input bytes. It might be better to pass the raw data from urandom to something like base64 or anything that produces a hex dump.


One simple way to make anything into readable characters:

$ head -c30 /dev/urandom | base64

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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