GNU/Linux >> Tutoriales Linux >  >> Linux

¿Por qué cat /dev/urandom colgó mi script bash?

Nunca debes usar cat con /dev/urandom . Tampoco debe usar ninguna utilidad que esté diseñada para archivos de texto.

/dev/urandom es un flujo continuo de datos aleatorios. Nunca producirá un final de archivo. Las lecturas almacenadas en búfer llenarán el búfer de lectura, por lo que incluso si está canalizando la salida de cat en algún otro programa, la lectura no terminará hasta que se cierre la tubería.

Nada de eso sería otra cosa que ineficiente, excepto que cuando lees /dev/urandom , estás consumiendo entropía (aleatoriedad), que es un recurso precioso. Una vez que se agota la entropía, /dev/urandom La salida será menos aleatoria, lo que anula el propósito. (Se recolectará más entropía, pero lleva un tiempo acumularse).

Todo esto se duplica para /dev/random , porque cuando se queda sin entropía, suele bloquearse. (Excepto en los sistemas operativos que hacen /dev/random un sinónimo de /dev/urandom .)

En consecuencia, siempre debe leer exactamente la cantidad de datos aleatorios que necesita, y no más.

Aparentemente, estás apuntando a 24 caracteres alfanuméricos. Hay 62 caracteres alfanuméricos posibles; simplificaría mucho las cosas si estuviera dispuesto a permitir que otros dos caracteres llevaran el total a 64. En ese caso, podría producir 24 caracteres extrayendo 18 bytes de aleatoriedad y pasándolos a través de un codificador base64. Para extraer una cantidad precisa de datos, use dd , que está diseñado para el propósito:

dd bs=18 count=1 if=/dev/urandom | base64 | tr +/ _.

(El tr al final traduce los dos caracteres no alfanuméricos producidos por base64 en dos caracteres diferentes que son más amigables con los nombres de archivo. Solo una sugerencia.)

Si está decidido a usar caracteres alfanuméricos precisos, podría usar una estrategia de rechazo similar a la que está usando actualmente, pero basada en lo anterior. Desafortunadamente, no es posible predecir exactamente cuánta entrada necesitará en este caso, por lo que el enfoque más simple es leer un poco más y volver a intentarlo en el raro caso de que no obtenga suficiente:

# Here we produce 28 characters each time
until s=$(dd bs=21 count=1 if=/dev/urandom |
           LC_ALL=C tr -cd A-Za-z0-9)
      ((${#s} >= 24)); do :; done
# When the loop ends we have at least 24 characters; truncate
s=${s:0:24} 

Si no tiene bash, puede reemplazar ((${#s} >= 24)) con [ ${#s} -ge 24 ] y s=${s:0:24} con s=$(printf %.24s $s)

Pero si solo está tratando de generar buenos nombres de archivo aleatorios, debe usar mktemp , que le permite especificar un esqueleto para los nombres y también verifica que el nombre generado no esté ya presente. Ver man mktemp .


En realidad cat /dev/urandom nunca termina por sí solo. Pero cuando head -1 lee la primera línea, sale, cerrando así stdin y cerrando una tubería. OS plantea SIGPIPE a fold también sale, y así sucesivamente, por lo que cat /dev/urandom termina eventualmente.

En tu caso, algo bloquea SIGPIPE , es decir, trap puede hacer eso:

$ trap '' PIPE 
$ cat /dev/urandom | LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w 24 | head -n 1
7FazO6mnsIow3ylkvEHB55jE
(hungs)

Intente volver a habilitarlo en subshell:

( trap - PIPE ; cat /dev/urandom | LC_ALL=C tr -dc 'a-zA-Z0-9' | fold -w 24 | head -n 1 )

Linux
  1. Cómo generar una contraseña aleatoria en Linux usando /dev/random

  2. ¿Cómo maneja Linux múltiples separadores de rutas consecutivas (/home////username///file)?

  3. Linux:¿Diferencia entre /dev/console, /dev/tty y /dev/tty0?

  4. Linux:¿Qué significa la letra 'u' en /dev/urandom?

  5. Cómo mapear dispositivos /dev/sdX y /dev/mapper/mpathY desde el dispositivo /dev/dm-Z

¿Por qué no puedo usar Cd en un script Bash?

Ejecute el comando bash en la canalización de jenkins

¿Cuándo debo usar /dev/shm/ y cuándo debo usar /tmp/?

¿Por qué Linux enumera las unidades NVMe como /dev/nvme0 en lugar de /dev/sda?

Cómo usa Linux /dev/tty y /dev/tty0

hacer eco o imprimir /dev/stdin /dev/stdout /dev/stderr