Kindle 电子墨水帮助 - 显示随机图像文件

Kindle 电子墨水帮助 - 显示随机图像文件

我对此完全是新手,但我正在尝试将其他人的代码改编为越狱的 Kindle 3(电子阅读器)。

我使用以下代码生成 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 有时会显示空白屏幕而不是图像之一。我猜测生成的随机数存在问题,这意味着无法找到具有匹配数字的 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。如果前导 0 被解释为八进制数,甚至可能会导致无效算术表达式问题。 (编辑:哦,我想这就是你在前面加上 1 的原因)

不管怎样……需要一段时间才能终止。并提出了一个问题,为什么你不只使用$RANDOM%32.对于较小的数字$RANDOM(限制为 0-32767)效果很好。

$RANDOM如果Kindle 的 busybox 中没有(可能是如果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 is ,pic_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()仅基于四舍五入到最接近的秒的当前时间,因此在很多情况下它是不合适的(任何与安全相关的事情,任何每秒可能有超过一次随机抽取的事情)。但在这里已经足够好了。

不要为每张图片分配一个编号并对编号范围进行硬编码,而是列出文件并随机选择一个。更确切地说:

  • 将位置参数设置为文件列表。
  • 使用 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 shell 和许多 BusyBox 安装中都可用的功能。)

相关内容