2015-09-15 67 views
3

以下簡短腳本打印一個隨機的十位二進制數:

#!/usr/bin/zsh 
point='' 
for i in `seq 1 10` 
do 
    echo $RANDOM >/dev/null 
    point=$point`if [ $RANDOM -gt 16383 ]; then echo 0; else echo 1; fi` 
done 
echo $point 

但是,如果我去掉明顯無用echo $RANDOM >/dev/null線,劇本始終打印要麼11111111110000000000

爲什麼?

+0

問題的標題現在有點有趣!如果我已經知道如此具體地標題這個問題,我可能不需要問一個問題...... –

+0

無可否認如此。但問題是,如果你在詢問之前搜索重複的東西時看到過這個標題(你*確實*搜索過重複的東西,對嗎?),你會認識到它是你的問題嗎? (如果沒有,也許「在子殼」需要被退出)。 –

+0

@CharlesDuffy我確實搜索了重複內容,並發現了一些確實無關的內容。如果我在結果中看到它,我至少會點擊這個標題。 =) –

回答

5

從手冊頁:

RANDOM的值形成故意重複的僞隨機序列;子引用 RANDOM將導致相同的僞隨機值,除非RANDOM的值在子shell調用之間的父shell中被引用或播種 。

echo的「無用」調用提供了一個參考,它允許由命令替換引發的子shell每次產生一個不同的值。

4

子shell(通過反引號,或它們的現代替代$()創建)執行從父shell不同的上下文中 - 這意味着,當他們退出,所有的過程,本地狀態的改變 - 包括隨機數生成器的狀態 - 被扔掉。

從父shell中的$RANDOM讀取更新RNG的狀態,這就是爲什麼echo $RANDOM >/dev/null有效。

也就是說,不要這樣做。做這樣的事情,它沒有子shell都:

point= 
for ((i=0; i<10; i++)); do 
    point+=$(((RANDOM > 16383) ? 0 : 1)) 
done 

如果你測試這個創造了超過10位 - 嘗試,比如,1000或10000 - 你還會發現,它執行好得多比原來的要好。

+1

這個答案和另一個答案之間是一個艱難的選擇。另一個包括最相關的文檔報價;但我非常讚賞替代代碼建議。 –

+1

絕對使用無外殼代碼;我只專注於解釋觀察到的行爲。 – chepner

+0

嗯。實際上,這可以通過使用三元數來縮短;我很想修改...... –

相關問題