GNU/Linux >> Linux Esercitazione >  >> Linux

Perché cat /dev/urandom ha bloccato il mio script bash?

Non dovresti mai usare cat con /dev/urandom . Né dovresti usare alcuna utilità progettata per i file di testo.

/dev/urandom è un flusso continuo di dati casuali. Non produrrà mai una fine del file. Le letture bufferizzate riempiranno il buffer di lettura, quindi anche se stai eseguendo il piping dell'output di cat in qualche altro programma, la lettura non verrà terminata finché la pipe non sarà chiusa.

Niente di tutto ciò sarebbe altro che inefficiente, tranne che quando leggi /dev/urandom , stai consumando entropia (casualità), che è una risorsa preziosa. Una volta esaurita l'entropia, /dev/urandom l'output di sarà meno casuale, il che vanifica lo scopo. (Sarà raccolta più entropia, ma ci vorrà un po' per accumularsi.)

Tutto questo vale il doppio per /dev/random , perché quando esaurisce l'entropia, di solito si blocca. (Tranne sui sistemi operativi che rendono /dev/random sinonimo di /dev/urandom .)

Di conseguenza, dovresti sempre leggere esattamente la quantità di dati casuali di cui hai bisogno e non di più.

A quanto pare, stai mirando a 24 caratteri alfanumerici. Ci sono 62 possibili caratteri alfanumerici; semplificherebbe notevolmente le cose se fossi disposto a consentire ad altri due caratteri di portare il totale a 64. In tal caso, potresti produrre 24 caratteri estraendo 18 byte di casualità e facendoli passare attraverso un codificatore base64. Per estrarre una quantità precisa di dati, usa dd , progettato per lo scopo:

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

(Il tr alla fine traduce i due caratteri non alfanumerici prodotti da base64 in due caratteri diversi che sono più compatibili con i nomi dei file. Solo un suggerimento.)

Se sei determinato a utilizzare esattamente caratteri alfanumerici, potresti utilizzare una strategia di rifiuto simile a quella che stai attualmente utilizzando, ma basata su quanto sopra. Sfortunatamente, non è possibile prevedere esattamente quanto input ti servirà in questo caso, quindi l'approccio più semplice è leggere un po' di più e riprovare nel raro caso in cui non ne hai abbastanza:

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

Se non hai bash, puoi sostituire ((${#s} >= 24)) con [ ${#s} -ge 24 ] e s=${s:0:24} con s=$(printf %.24s $s)

Ma se stai solo cercando di generare buoni nomi di file casuali, dovresti usare mktemp , che consente di specificare uno scheletro per i nomi e verifica anche che il nome generato non sia già presente. Vedi man mktemp .


In realtà cat /dev/urandom non finisce mai da solo. Ma quando head -1 legge la prima riga, esce, chiudendo così stdin e chiudendo una pipe. OS alza SIGPIPE a fold anche esce e così via, quindi cat /dev/urandom finisce alla fine.

Nel tuo caso, qualcosa che blocca SIGPIPE , ovvero trap può farlo:

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

Prova a riattivarlo in subshell:

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

Linux
  1. Quando usare /dev/random vs /dev/urandom?

  2. Perché non posso usare Cd in uno script Bash??

  3. Linux:cosa significa la lettera "u" in /dev/urandom?

  4. Come mappare il dispositivo /dev/sdX e /dev/mapper/mpathY dal dispositivo /dev/dm-Z

  5. Quando dovrei usare /dev/shm/ e quando dovrei usare /tmp/?

Bash =~ Regex e HTTPS://regex101.com/?

Quanto sono portatili /dev/stdin, /dev/stdout e /dev/stderr?

Come codificare in base64 /dev/random o /dev/urandom?

Esegui il comando bash sulla pipeline jenkins

Linux:differenza tra /dev/console , /dev/tty e /dev/tty0

Come Linux usa /dev/tty e /dev/tty0