Why can't tr read from /dev/urandom on OSX?

Based on the error message that you get, I don't think /dev/urandom is the problem. If it were, I'd expect an error like "no such file or directory".

I searched for the error message you got and found this, which seems like it might be relevant to your issue: http://nerdbynature.de/s9y/2010/04/11/tr-Illegal-byte-sequence

Basically, specify the locale by prepending the tr command with LC_CTYPE=C:

LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs

Your tr attempts to interpret its input as text in UTF-8 encoding. So it will complain and abort upon the first byte sequence which is not valid UTF-8. Prefixing tr with LC_ALL=C or LC_CTYPE=C will export that variable into the environment of tr, thus changing its idea of the local character set to the C standard, i.e. everything is just a sequence of opaque bytes.

By the way, is the sequence \)-+ in your command intentional? This includes * as well, which you already included, but does not include - itself as you might have intended. Better to write one of these instead:

LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()\-+=' < /dev/urandom
LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)\\-+= < /dev/urandom

As others have indicated, your problem isn't that /dev/urandom is missing, but rather how tr works on OS X. Instead of messing around with enviornment varialbes, use perl in place of tr:

perl -pe 'binmode(STDIN, ":bytes"); tr/A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+=//dc;' < /dev/urandom | head -c 32; echo

This has the advantage of being portable across OS X, Redhat and Ubuntu.

(I also removed the pipe to xargs, replacing witch echo, to get a newline at the end of the output.)

Tags:

Random

Tr

Osx