Kindle E-Inkヘルプ - ランダム画像ファイルを表示する

Kindle E-Inkヘルプ - ランダム画像ファイルを表示する

私はこの分野に完全に慣れていませんが、脱獄されたKindle 3(e-reader)に他の人のコードを適用しようとしています。

次のコードを使用して、0とX(ここでXは私が持っている画像の数、現在33)の間の任意の数字を生成し、数時間ごとに(現在は2時間ごとに)任意の画像を表示できます。cronスクリプトを実行します。

#generate random number between my 33 images (compatible with busybox)
n=32
while [ $n -ge 32 ]; do
n=1$(</dev/urandom tr -dc 0-9 | dd bs=5 count=1 2>/dev/null)
n=$((n-100000))
done
ImageNumber=$n

#My images are numbered as follows - pic_0.png, pic_1.png, pic_3.png... etc
SelectedImage=$( find /mnt/us/timelit/images/pic_${ImageNumber}*.png)

# clear the screen
eips -c

# show that image
eips -g $SelectedImage

うまくいきますが、解決すべきいくつかの問題があります。

1) スクリプトの乱数生成部分が数字を生成する前に時間の経過とともに変化するため、問題があるようです(下記ログ参照)。

14:00:02: Script started
14:02:43: Random number is 2 
14:02:44: Image shown is pic_2.png 
15:00:02: Script started
15:00:19: Random number is 18 
15:00:20: Image shown is pic_18.png 
16:00:01: Script started
16:02:44: Random number is 10 
16:02:45: Image shown is pic_10.png  

2)Kindleでは、画像の1つではなく空白の画面が表示されることがあります。生成された乱数に問題があるようです。つまり、一致する数のPNGが見つからず、Kindleが空白として表示されます。

どんな助けでも大変感謝します。

答え1

#generate random number between my 33 images (compatible with busybox)
n=32
while [ $n -ge 32 ]; do
n=1$(</dev/urandom tr -dc 0-9 | dd bs=5 count=1 2>/dev/null)
n=$((n-100000))
done
ImageNumber=$n

したがって、ここでは00000-99999の乱数を生成し、32未満に低下した場合にのみ終了します。確率は100,000に32です。先行ゼロが8進数として解釈されると、誤った算術式の問題が発生する可能性があります。 (編集:ああ、だから前に1を追加したと思います)

とにかく…終了するのに少し時間がかかると思います。そして$RANDOM%32より小さい数字(0-32767に制限)で$RANDOMうまく動作します。

$RANDOMKindleのビジボックス(おそらくそうです)にない場合はCONFIG_ASH_RANDOM_SUPPORT=n...を使用して単一の番号を取得するtrか、hexdump利用可能な場合は単に使用できます。

それにもかかわらず、whileループは非常に非効率的で無意味です。

ループのない例:

random=1$(</dev/urandom tr -dc 0-9 | dd bs=5 count=1 2>/dev/null)
ImageNumber=$(($random % 32))

tr必要なものよりも5つのランダムバイトを読み取る必要があるため、まだ少し非効率的です(256の数字を読む機会の10)。

可能であればhexdump(固定されたランダム3バイトを読む):

 random=0x$(hexdump -v -e '3/1 "%02x"' -n 3 /dev/urandom)
 ImageNumber=$(($random % 32))
#My images are numbered as follows - pic_0.png, pic_1.png, pic_3.png... etc
SelectedImage=$( find /mnt/us/timelit/images/pic_${ImageNumber}*.png)

ImageNumberが1の場合、式はpic_1*.pngwhich might be but ispic_1.pngなどに変換されます。ファイル名に余分な文字が含まれていない場合は、*を削除してください。それ以外の場合は、別の区切り文字が必要です(類似したファイル名を許可するには)。pic_10-19.pngpic-100-199.pngpic_${ImageNumber}_*.pngpic_1_spaceship.png

いずれにしてもクエリをスキップし、式を直接使用できます。

eips -g /mnt/us/timelit/images/pic_${ImageNumber}.png

答え2

バラよりフロストスーツの答えコードが正しく動作しない理由私はさまざまな解決策を提示します。

BusyBox環境にawkが含まれている場合、このアプリケーションに適した乱数を生成する簡単な方法は次のとおりです。

awk -v n=32 'BEGIN {srand(); print int(rand() * n); exit}'

srand()最も近い秒単位で四捨五入された現在の時間のみに基づいているため、多くの場合に不適切です(セキュリティに関連するすべて、1秒あたり1回以上のランダム抽選がある可能性があるすべて)。しかし、ここでは十分に大丈夫です。

各写真に番号を割り当て、番号の範囲をハードコードするのではなく、ファイルを一覧表示してランダムに1つを選択してください。具体的には:

  • 位置引数をファイルリストに設定します。
  • 位置パラメータをランダムに選択するには、awkを使用してください。
  • 場所パラメータでファイル名を選択します。
set -- /mnt/us/timelit/images/pic*.png
i=$(awk -v n=$# 'BEGIN {srand(); print int(rand() * n ) + 1; exit}')
eval "SelectedImage=\${$i}"

eips -c
eips -g $SelectedImage

awkに画像ファイルを直接選択するように要求することもできますが、ファイルが多い場合はコマンドラインの長さ制限が発生する可能性があります。

SelectedImage=$(awk '
    BEGIN {srand(); print ARGV[int(rand() * (length(ARGV)-1) + 1)]; exit}
  ' /mnt/us/timelit/images/pic*.png)

(bashおよびGNUユーティリティを含むより完全な環境がある場合は、いくつかのタスクを実行するより簡単な方法があります。私の答えは、すべてのPOSIXシェルと多くのBusyBoxインストールで利用可能な機能に忠実です。)

関連情報