GNU/Linux >> Tutoriels Linux >  >> Linux

Pourquoi cat /dev/urandom a suspendu mon script bash ?

Vous ne devez jamais utiliser cat avec /dev/urandom . Vous ne devez pas non plus utiliser d'utilitaires conçus pour les fichiers texte.

/dev/urandom est un flux continu de données aléatoires. Il ne produira jamais de fin de fichier. Les lectures tamponnées rempliront le tampon de lecture, donc même si vous dirigez la sortie de cat dans un autre programme, la lecture ne sera pas terminée tant que le tube ne sera pas fermé.

Rien de tout cela ne serait autre chose qu'inefficace, sauf que lorsque vous lisez /dev/urandom , vous utilisez de l'entropie (aléatoire), qui est une ressource précieuse. Une fois l'entropie épuisée, /dev/urandom La sortie sera moins aléatoire, ce qui va à l'encontre de l'objectif. (Plus d'entropie sera collectée, mais cela prend un certain temps pour s'accumuler.)

Tout cela double pour /dev/random , car lorsqu'il manque d'entropie, il se bloque généralement. (Sauf sur les OS qui font /dev/random un synonyme de /dev/urandom .)

Par conséquent, vous devez toujours lire exactement la quantité de données aléatoires dont vous avez besoin, et pas plus.

Apparemment, vous visez 24 caractères alphanumériques. Il y a 62 caractères alphanumériques possibles; cela simplifierait grandement les choses si vous étiez prêt à autoriser deux autres caractères à porter le total à 64. Dans ce cas, vous pourriez produire 24 caractères en extrayant 18 octets de caractère aléatoire et en les faisant passer par un encodeur base64. Pour extraire une quantité précise de données, utilisez dd , qui est conçu dans le but :

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

(Le tr à la fin traduit les deux caractères non alphanumériques produits par base64 en deux caractères différents qui sont plus conviviaux pour les noms de fichiers. Juste une suggestion.)

Si vous êtes déterminé à utiliser précisément des caractères alphanumériques, vous pouvez utiliser une stratégie de rejet similaire à celle que vous utilisez actuellement, mais basée sur ce qui précède. Malheureusement, il n'est pas possible de prédire exactement la quantité d'entrée dont vous aurez besoin dans ce cas, donc l'approche la plus simple est de lire un peu plus et de réessayer dans les rares cas où vous n'en obtenez pas assez :

# 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 vous n'avez pas bash, vous pouvez remplacer ((${#s} >= 24)) avec [ ${#s} -ge 24 ] et s=${s:0:24} avec s=$(printf %.24s $s)

Mais si vous essayez simplement de générer de bons noms de fichiers aléatoires, vous devez utiliser mktemp , qui vous permet de spécifier un squelette pour les noms, et vérifie également que le nom généré n'est pas déjà présent. Voir man mktemp .


En fait cat /dev/urandom ne se termine jamais tout seul. Mais quand head -1 lit la première ligne, il sort, fermant ainsi stdin et fermant un tube. Le système d'exploitation génère SIGPIPE à fold est également des sorties, et ainsi de suite, donc cat /dev/urandom se termine finalement.

Dans votre cas, quelque chose bloque SIGPIPE , c'est-à-dire que trap peut faire cela :

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

Essayez de le réactiver dans le sous-shell :

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

Linux
  1. Linux :Différence entre /dev/console , /dev/tty et /dev/tty0 ?

  2. Bash =~ Regex et Https://regex101.com/?

  3. Quelle est la portabilité de /dev/stdin, /dev/stdout et /dev/stderr ?

  4. Pourquoi ne puis-je pas utiliser Cd dans un script Bash ? ?

  5. Linux – Que signifie la lettre « u » dans /dev/urandom ?

Quand utiliser /dev/random contre /dev/urandom ?

Comment mapper les périphériques /dev/sdX et /dev/mapper/mpathY à partir du périphérique /dev/dm-Z

Comment Linux utilise /dev/tty et /dev/tty0

Est-ce une erreur de lier /dev/random à /dev/urandom sous Linux ?

echo ou print /dev/stdin /dev/stdout /dev/stderr

Pourquoi < ou > sont-ils nécessaires pour utiliser /dev/tcp