GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Warum hat cat /dev/urandom mein Bash-Skript aufgehängt?

Sie sollten niemals cat verwenden mit /dev/urandom . Sie sollten auch keine Dienstprogramme verwenden, die für Textdateien entwickelt wurden.

/dev/urandom ist ein kontinuierlicher Strom zufälliger Daten. Es wird niemals ein Dateiende erzeugt. Gepufferte Lesevorgänge füllen den Lesepuffer, also auch dann, wenn Sie die Ausgabe von cat weiterleiten in ein anderes Programm, wird der Lesevorgang erst beendet, wenn die Pipe geschlossen wird.

Nichts davon wäre alles andere als ineffizient, außer wenn Sie /dev/urandom lesen verbrauchen Sie Entropie (Zufälligkeit), die eine wertvolle Ressource ist. Sobald die Entropie aufgebraucht ist, /dev/urandom Die Ausgabe von ist weniger zufällig, was den Zweck verfehlt. (Es wird mehr Entropie gesammelt, aber der Aufbau dauert eine Weile.)

All dies geht doppelt für /dev/random , denn wenn ihm die Entropie ausgeht, blockiert er normalerweise. (Außer auf Betriebssystemen, die /dev/random machen ein Synonym für /dev/urandom .)

Folglich sollten Sie immer genau die Menge an Zufallsdaten lesen, die Sie benötigen, und nicht mehr.

Anscheinend zielen Sie auf 24 alphanumerische Zeichen ab. Es gibt 62 mögliche alphanumerische Zeichen; Es würde die Dinge erheblich vereinfachen, wenn Sie zwei weitere Zeichen zulassen würden, um die Gesamtzahl auf 64 zu bringen. In diesem Fall könnten Sie 24 Zeichen erzeugen, indem Sie 18 Bytes Zufall extrahieren und durch einen Base64-Encoder leiten. Um eine genaue Datenmenge zu extrahieren, verwenden Sie dd , die für den folgenden Zweck entwickelt wurde:

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

(Die tr übersetzt am Ende die beiden nicht-alphanumerischen Zeichen, die von base64 erzeugt werden in zwei verschiedene Zeichen, die Dateinamen-freundlicher sind. Nur ein Vorschlag.)

Wenn Sie entschlossen sind, genau alphanumerische Zeichen zu verwenden, können Sie eine ähnliche Zurückweisungsstrategie wie die verwenden, die Sie derzeit verwenden, jedoch auf der Grundlage des oben Gesagten. Leider ist es nicht möglich, genau vorherzusagen, wie viel Eingabe Sie in diesem Fall benötigen, daher ist der einfachste Ansatz, ein wenig mehr zu lesen und es in dem seltenen Fall, dass Sie nicht genug bekommen, erneut zu versuchen:

# 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} 

Wenn Sie keine bash haben, können Sie ((${#s} >= 24)) ersetzen mit [ ${#s} -ge 24 ] und s=${s:0:24} mit s=$(printf %.24s $s)

Aber wenn Sie nur versuchen, gute zufällige Dateinamen zu generieren, sollten Sie mktemp verwenden , mit dem Sie ein Skelett für die Namen angeben können, und überprüft außerdem, ob der generierte Name nicht bereits vorhanden ist. Siehe man mktemp .


Eigentlich cat /dev/urandom endet nie von alleine. Aber wenn head -1 liest die erste Zeile, es wird beendet, wodurch stdin geschlossen und eine Pipe geschlossen wird. Betriebssystem löst SIGPIPE aus bis fold ist auch beendet, und so weiter, also cat /dev/urandom endet irgendwann.

In Ihrem Fall blockiert etwas SIGPIPE , d.h. trap kann das:

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

Versuchen Sie, es in der Subshell erneut zu aktivieren:

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

Linux
  1. Wie behandelt Linux mehrere aufeinanderfolgende Pfadtrennzeichen (/home////username///file)?

  2. Wie portabel sind /dev/stdin, /dev/stdout und /dev/stderr?

  3. Wann sollte /dev/random vs. /dev/urandom verwendet werden?

  4. Warum kann ich Cd nicht in einem Bash-Skript verwenden?

  5. Linux – Was bedeutet der Buchstabe „u“ in /dev/urandom?

Wann sollte ich /dev/shm/ verwenden und wann sollte ich /tmp/?

Linux:Unterschied zwischen /dev/console , /dev/tty und /dev/tty0

Wie Linux /dev/tty und /dev/tty0 verwendet

Ist es falsch, /dev/random unter Linux mit /dev/urandom zu verknüpfen?

echo oder print /dev/stdin /dev/stdout /dev/stderr

Warum sind < oder > erforderlich, um /dev/tcp