如何在sh(/ bin/sh,而不是bash)中的0-60之間生成隨機數?這是一個衛星箱,沒有$RANDOM
變量,和其他貨物[cksum,od(od -vAn -N4 -tu4 </dev/urandom)]。sh在範圍之間的隨機數
我想隨機化一個crontab作業的時間。
如何在sh(/ bin/sh,而不是bash)中的0-60之間生成隨機數?這是一個衛星箱,沒有$RANDOM
變量,和其他貨物[cksum,od(od -vAn -N4 -tu4 </dev/urandom)]。sh在範圍之間的隨機數
我想隨機化一個crontab作業的時間。
如果你已經TR,頭和/ dev/urandom的,你可以這樣寫:
tr -cd 0-9 </dev/urandom | head -c 3
然後,你必須使用,其餘運營商擺在0-60範圍。
如何使用納秒的系統時間?
date +%N
這不像你需要密碼有用的數字在這裏。
根據其/bin/sh
它的版本,你可以做:
$((date +%N
%60))
如果它不支持$(())
語法,但你有DC ,你可以嘗試:
dc -e `date +%N`' 60 % p'
不知道哪個操作系統的版本/bin/sh
或者什麼 工具可用,很難拿出保證正常工作的解決方案。
你有awk嗎?你可以調用awk的rand()函數。例如:
awk 'BEGIN { printf("%d\n",rand()*60) }' < /dev/null
我總是得到號碼「50」 – Adrian 2011-01-12 23:34:40
@Adrian:你必須播種隨機數發生器:`awk'BEGIN {srand(); printf(「%d \ n」,rand()* 60)}'`。如果只有一個`BEGIN`子句,則不需要重定向。 – 2011-01-13 04:35:47
value=`od -An -N2 -tu2 /dev/urandom` minutes=`expr $value % 60`
種子將是0和65535之間,這是不的偶數倍的60,所以分鐘0-15具有被選擇稍大的機會的ob,但差異可能是不重要的。
如果你想做到盡善盡美,用「OD - 一個-N1 -tu1」和循環,直到值小於240
測試與busybox的OD。每當產生數由0開始,但有其他位數大於7
馬可的回答會失敗,因爲它被解釋爲八進制,我建議:
tr -cd 0-9 </dev/urandom | head -c 4 | sed -e 's/^00*//
特殊的情況下,要處理的任何進一步,例如建立一個範圍:
RANDOM=`tr -cd 0-9 </dev/urandom | head -c 4 | sed -e 's/^00*//'`
RND50=$((($RANDOM%50)+1)) // random number between 1 and 50
我知道這個職位是舊的,但建議的答案是不產生均勻無偏的隨機數。該接受的答案基本上是這樣的:
% echo $(($(tr -cd 0-9 </dev/urandom | head -c 3) % 60))
這個建議的問題是,從/dev/urandom
選擇一個3位數,範圍爲0-999,共1000號。但是,千分之六十不均勻。因此,你會偏向產生0-959,稍微超過960-999。
第二個答案,而創造性的使用納秒從你的時鐘,從相同的偏頗做法受到影響:
% echo $(($(date +%N) % 60))
範圍爲納秒是0-999,999,999,爲1個十億的數字。所以,如果你將這個結果除以60,那麼你將再次偏向產生0-999,999,959,略多於999,999,960-999,999,999。
所有其餘的答案是相同的偏見不均勻的一代。
要生成0-59範圍內的無偏差統一隨機數(我假設他的意思是,而不是0-60,如果他試圖隨機化crontab(1)
條目),我們需要強制輸出爲一個倍數60.
首先,我們將隨機生成一個32位的數字從0到4294967295:
% RNUM=$(od -An -N4 -tu2 /dev/urandom | awk '{print $1}')
現在,我們將迫使我們的產品範圍爲$ MIN之間和4294967295這是一個多60:
% MIN=$((2**32 % 60)) # 16
這意味着:
4294967296 - 16 = 4294967280
4294967280/60 = 71582788.0
換句話說,我的[16,4294967295]範圍是60恰好倍數所以,每次我在該範圍內產生數字,然後除以60,將同樣可能與任何其他號碼一樣。因此,我有一個無偏差的數字0-59的生成器(如果添加1,則爲1-60)。
唯一剩下要做的就是確保我的號碼是16到4294967295之間。如果我的數小於16,那麼我需要生成一個新的號碼:
% while [ $RNUM -lt $MIN ]; do RNUM=$(od -An -N1 -tu2 /dev/urandom); done
% MINUTE=$(($RNUM % 60))
把一切一起復制/粘貼goodnees:
#!/bin/bash
RNUM=$(od -An -N4 -tu2 /dev/urandom | awk '{print $1}')
MIN=$((2**32 % 60))
while [ $RNUM -lt $MIN ]; do RNUM=$(od -An -N1 -tu2 /dev/urandom); done
MINUTE=$(($RNUM % 60))
可惜的是不注日期的工作,沒有直流../bin/sh的--help /bin/sh的--help BusyBox的v1.15.3(2010-07- 21 18:00:33 CEST)多方通話二進制 – Adrian 2011-01-12 23:40:16