コマンドラインから/dev/random
(または/dev/urandom
)を使用する方法を探しています。特に、stdin
乱数のストリームをstdout
(1行に1つずつ)書き込むようなストリームの使い方を知りたいのです。
マシンのアーキテクチャがネイティブでサポートしているすべての数値型の乱数に興味があります。たとえば、64ビットアーキテクチャの場合、これらには64ビットの符号付き整数と符号なし整数、および64ビット浮動小数点数が含まれます。範囲に関する限り、さまざまな数値タイプの最大範囲で十分です。
Perl、Pythonなどの多目的インタープリターでこれをすべて行う方法を知っていますが、シェルからの「より単純な」ツールでこれを行う方法を知りたいのです。(「より単純」とは、「非常に最小限のUnixインストールでも利用できる可能性が高い」という意味です。)
基本的に、この問題により、コマンドラインでバイナリデータを文字列表現に変換する問題が軽減されます。(たとえば、これは機能しませんprintf '%f\n' $(head -c8 /dev/random)
。)
シェルにとらわれない答えを探しています。また、間の違い/dev/random
とは、/dev/urandom
この質問のために重要ではありません。結果のセマンティクスが異なる場合でも、1つの手順で機能する手順が他の手順でも機能することを期待しています。
EightBitTonyの答えをtoints
以下の関数などに変換しました。
使用例:
% < /dev/urandom toprobs -n 5
0.237616281778928
0.85578479125532
0.0330049682019756
0.798812391655243
0.138499033902422
備考:
hexdump
代わりに使用しod
ているのは、希望どおりに出力をフォーマットする簡単な方法が得られたからです。- 厄介なことに、
hexdump
64ビット整数(wtf ???)はサポートされていません。 - 関数のインターフェイスは機能する必要があります(たとえば、それら
-n5
も受け入れる必要があります-n 5
)が、私のかわいそうなシェルプログラミングスキルを考えると、これは私がすばやくまとめることができる最高のものでした。(コメント/改善はいつものように歓迎します。)
この演習で得た大きな驚きは、シェルで最も基本的な数値をプログラムするのがどれほど難しいかを発見することでした(たとえば、16進数の浮動小数点数を読み取る、または最大のネイティブ浮動小数点数を取得する)...
_tonums () {
local FUNCTION_NAME=$1 BYTES=$2 CODE=$3
shift 3
local USAGE="Usage: $FUNCTION_NAME [-n <INTEGER>] [FILE...]"
local -a PREFIX
case $1 in
( -n ) if (( $# > 1 ))
then
PREFIX=( head -c $(( $2 * $BYTES )) )
shift 2
else
echo $USAGE >&2
return 1
fi ;;
( -* ) echo $USAGE >&2
return 1 ;;
( * ) PREFIX=( cat ) ;;
esac
local FORMAT=$( printf '"%%%s\\n"' $CODE )
$PREFIX "$@" | hexdump -ve $FORMAT
}
toints () {
_tonums toints 4 d "$@"
}
touints () {
_tonums touints 4 u "$@"
}
tofloats () {
_tonums tofloats 8 g "$@"
}
toprobs () {
_tonums toprobs 4 u "$@" | perl -lpe '$_/=4294967295'
}
tr -cs '[:digit:]' '[\n*]' </dev/urandom
整数のみを与える必要があります。