cut lerá a entrada até o final do arquivo e cortará uma parte de cada linha. Com os dois primeiros comandos, você não vê nada, pois tr remove qualquer nova linha e, portanto, cut nunca vê uma linha completa para processar. No último, o tr remove novamente as novas linhas para que você não veja como cut manteve as linhas com um determinado tamanho.
Supondo que seu utilitário head suporta a opção -c <characters> , você pode usá-lo para obter um número fixo de bytes. Se não, use dd . ( dd bs=1 count=NNN < /dev/urandom )
Então, isso produziria 32 alfanuméricos (e uma nova linha):
tr -cd 'A-Za-z0-9' < /dev/urandom | head -c32 ; echo
Embora, apenas por princípio, isso é um desperdício, pois o tr remove aproximadamente 3/4 ou os bytes de entrada brutos. Talvez seja melhor passar os dados brutos de urandom para algo como base64 ou qualquer coisa que produza um despejo hexadecimal.