GNU/Linux >> Belajar Linux >  >> Linux

Mengapa cat /dev/urandom menggantung skrip bash saya?

Anda tidak boleh menggunakan cat dengan /dev/urandom . Anda juga tidak boleh menggunakan utilitas apa pun yang dirancang untuk file teks.

/dev/urandom adalah aliran terus menerus dari data acak. Itu tidak akan pernah menghasilkan akhir file. Bacaan buffer akan mengisi buffer baca, bahkan jika Anda mem-pipe output dari cat ke beberapa program lain, pembacaan tidak akan dihentikan hingga pipa ditutup.

Semua itu tidak lain adalah tidak efisien, kecuali ketika Anda membaca /dev/urandom , Anda menggunakan entropi (keacakan), yang merupakan sumber daya berharga. Setelah entropi habis, /dev/urandom output akan kurang acak, yang mengalahkan tujuannya. (Lebih banyak entropi akan dikumpulkan, tetapi perlu waktu lama untuk membangunnya.)

Semua ini berfungsi ganda untuk /dev/random , karena ketika kehabisan entropi, biasanya diblokir. (Kecuali pada OS yang membuat /dev/random sinonim untuk /dev/urandom .)

Akibatnya, Anda harus selalu membaca dengan tepat jumlah data acak yang Anda perlukan, dan tidak lebih.

Rupanya, Anda membidik 24 karakter alfanumerik. Ada 62 kemungkinan karakter alfanumerik; itu akan sangat menyederhanakan banyak hal jika Anda bersedia mengizinkan dua karakter lain untuk menjadikan totalnya menjadi 64. Dalam hal ini, Anda dapat menghasilkan 24 karakter dengan mengekstraksi 18 byte acak dan meneruskannya melalui encoder base64. Untuk mengekstrak jumlah data yang tepat, gunakan dd , yang dirancang untuk tujuan:

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

(tr pada akhirnya menerjemahkan dua karakter non-alfanumerik yang dihasilkan oleh base64 menjadi dua karakter berbeda yang lebih ramah nama file. Hanya saran.)

Jika Anda bertekad untuk menggunakan karakter alfanumerik yang tepat, Anda dapat menggunakan strategi penolakan yang serupa dengan yang Anda gunakan saat ini, tetapi berdasarkan hal di atas. Sayangnya, tidak mungkin untuk memprediksi dengan tepat berapa banyak masukan yang Anda perlukan dalam kasus ini, jadi pendekatan paling sederhana adalah dengan membaca sedikit tambahan, dan mencoba lagi jika Anda tidak mendapatkan cukup:

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

Jika Anda tidak memiliki bash, Anda dapat mengganti ((${#s} >= 24)) dengan [ ${#s} -ge 24 ] dan s=${s:0:24} dengan s=$(printf %.24s $s)

Tetapi jika Anda hanya mencoba membuat nama file acak yang bagus, Anda harus menggunakan mktemp , yang memungkinkan Anda menentukan kerangka untuk nama, dan juga memverifikasi bahwa nama yang dihasilkan belum ada. Lihat man mktemp .


Sebenarnya cat /dev/urandom tidak pernah berakhir dengan sendirinya. Tetapi ketika head -1 membaca baris pertama, keluar, sehingga menutup stdin dan menutup pipa. OS memunculkan SIGPIPE ke fold juga keluar, dan seterusnya, jadi cat /dev/urandom akhirnya berakhir.

Dalam kasus Anda, ada sesuatu yang memblokir SIGPIPE , yaitu trap dapat melakukan itu:

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

Coba aktifkan kembali di subkulit:

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

Linux
  1. Cara membuat kata sandi acak di linux menggunakan /dev/random

  2. Bagaimana Linux Menangani Beberapa Pemisah Jalur Berturut-turut (/home////username///file)?

  3. Seberapa Portabel /dev/stdin, /dev/stdout Dan /dev/stderr?

  1. Linux – Apa Arti Huruf 'u' Di /dev/urandom?

  2. Cara memetakan perangkat /dev/sdX dan /dev/mapper/mpathY dari perangkat /dev/dm-Z

  3. kernel:menonaktifkan /dev/kmem dan /dev/mem

  1. Linux:Perbedaan Antara /dev/console , /dev/tty Dan /dev/tty0?

  2. gema atau cetak /dev/stdin /dev/stdout /dev/stderr

  3. Mengapa < atau > diperlukan untuk menggunakan /dev/tcp