GNU/Linux >> Linux の 問題 >  >> Linux

cat /dev/urandom が bash スクリプトをハングさせたのはなぜですか?

cat は絶対に使用しないでください /dev/urandom で .また、テキスト ファイル用に設計されたユーティリティも使用しないでください。

/dev/urandom ランダム データの連続ストリームです。ファイルの終わりを生成することはありません。バッファリングされた読み取りは読み取りバッファを満たすため、cat の出力をパイプしても 他のプログラムに挿入すると、パイプが閉じられるまで読み取りは終了しません。

/dev/urandom を読むときを除いて、どれも非効率的です。 、貴重なリソースであるエントロピー(ランダム性)を使い果たしています。エントロピーが使い果たされると、/dev/urandom の出力はランダム性が低くなり、目的に反します。 (より多くのエントロピーが収集されますが、蓄積するのに時間がかかります。)

/dev/random の場合、これらすべてが 2 倍になります 、エントロピーを使い果たすと、通常はブロックされるためです。 (/dev/random を作成する OS を除く) /dev/urandom の同義語 .)

したがって、常に必要な量のランダム データを正確に読み取る必要があり、それ以上は読み取らないでください。

どうやら英数字24文字を狙っているようですね。使用可能な英数字は 62 文字です。他の 2 文字の合計を 64 にすることができれば、非常に簡単になります。その場合、18 バイトのランダム性を抽出して base64 エンコーダーに渡すことで、24 文字を生成できます。正確な量のデータを抽出するには、dd を使用します 、目的のために設計されています:

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

(tr 最後に、base64 によって生成された 2 つの英数字以外の文字を変換します よりファイル名に適した 2 つの異なる文字に変換されます。単なる提案です。)

正確に英数字を使用することに決めた場合は、現在使用しているものと同様の拒否戦略を使用できますが、上記に基づいています.残念ながら、この場合に必要な入力量を正確に予測することはできません。そのため、最も簡単な方法は、少し余分に読み取り、十分に得られないまれなケースで再試行することです:

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

bash がない場合は、((${#s} >= 24)) を置き換えることができます [ ${#s} -ge 24 ] で と s=${s:0:24} s=$(printf %.24s $s)

しかし、適切なランダムなファイル名を生成しようとしているだけなら、 mktemp を使用する必要があります これにより、名前のスケルトンを指定でき、生成された名前がまだ存在しないことも確認できます。 man mktemp を参照 .


実際には cat /dev/urandom それ自体で終わることはありません。しかし head -1 の場合 最初の行を読み取って終了し、標準入力を閉じてパイプを閉じます。 OS が SIGPIPE を発生させます fold へ も終了などなので、 cat /dev/urandom 最終的に終了します。

あなたの場合、SIGPIPE をブロックする何か 、つまりtrapはそれを行うことができます:

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

サブシェルで再度有効にしてみてください:

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

Linux
  1. / dev/randomを使用してLinuxでランダムパスワードを生成する方法

  2. Linux:/ dev / console、/ dev / tty、/ dev / tty0の違いは?

  3. /dev/random または /dev/urandom を base64 でエンコードする方法は?

  1. Linuxは複数の連続したパスセパレーター(/ home //// username /// file)をどのように処理しますか?

  2. Bash =〜正規表現とHttps://regex101.com/?

  3. Linux:/dev/console 、 /dev/tty 、 /dev/tty0 の違い

  1. / dev / stdin、/ dev / stdout、および/ dev / stderrはどの程度移植可能ですか?

  2. / dev/randomと/dev/ urandomをいつ使用するか?

  3. BashスクリプトでCdを使用できないのはなぜですか?