No, it's not entirely secure. Let's look at each of the commands:
dd if=/dev/urandom bs=256 count=1 2> /dev/null
This will read a single 256 byte block from
/dev/urandom, a cryptographically secure random source. The problem starts here, and is related to this 256 byte limit. In fact, you do not even need to use
dd here. The next command is perfectly able to read from a block device on its own.
LC_ALL=C tr -dc 'A-Za-z0-9'
This command strips out all characters that are not alphanumeric. The
LC_ALL=C limits the charset to plain ASCII, where
[:alnum:] will match 62 characters. Symbols and unprintable characters will be removed. The issue now is that only 256 bytes are given to this command, so what if too few of those bytes are alphanumeric? The
tr command will happily take 256 bytes of input and spit out only a couple bytes of output if only a couple bytes match the filter.
This command simply truncates the output to 20 bytes. The actual output will vary between 0 and 20 characters.* Statistically, it is most likely for it to output the entire 20 characters each time.
A superior way to get random alphanumeric characters can be done with fewer commands. This will have
tr read as much data from
/dev/urandom as it needs, continuously spitting out alphanumeric ASCII to the next command. As soon as
head has the 20 bytes it has asked for, it will close the pipe, causing
tr to stop reading random data and exit. This is what you should use:
LC_ALL=C tr -dc '[:alnum:]' < /dev/urandom | head -c20
This will guarantee 20 random characters, with an equivalent strength of log2(6220) ≈ 119.1 bits.
* The risk is largely theoretical. Each byte has a (256 - 62) / 256 chance (about 76%) of not being alphanumeric. The probability that at least 256 - 20 bytes are not alphanumeric is very low, but non-zero: (194 / 256)236 ≈ 3.8 × 10-28.