
Это продолжение моей предыдущей темы: Передача команды date в переменную?
Хорошо, эффективно я бы хотел, чтобы /dev/urandom сгенерировал для меня 4 цифры. И поместил их в переменную.
Вот пример моего bash-скрипта:-
#!/bin/bash
for (( c=0; c<=10; c++))
do
a="$(tr -dc '[:digit:]' < /dev/urandom | fold -w 4)"
echo $a
done
Единственная причина, по которой я хочу «отобразить» результаты, заключается в том, что я хочу действительно увидеть, что /dev/urandom правильно сгенерировал для меня 4 цифры.
Для моего bash-скрипта, который я хочу создать, мне нужно сделать это программно, поскольку я хочу выполнять дальнейшие операции с полученными результатами.
Поэтому мне не нужно «повторять» результаты.a="$(tr -dc '[:digit:]' < /dev/urandom | fold -w 4)"
На самом деле помещаем 4 случайные цифры в переменную «a»? Когда я вывожу «a» из своего скрипта, я просто получаю зависшую консоль и мне приходится использовать «CTRL+C», чтобы вернуть консоль обратно.
Все, что я пытаюсь сделать, это поместить 4 случайные цифры из /dev/urandom в переменную.
Я новичок в написании скриптов bash, поэтому буду рад любым советам и заранее благодарен за любую помощь или предложения.
решение1
Если вам не нужна безопасность, вы можете использовать встроенные в bash функцииRANDOM
переменная. Чтобы получить случайное число от 0 до 9999 включительно, $((RANDOM % 10000))
дает небольшое смещение в сторону значений меньше 767, поскольку значения $RANDOM
равномерны в диапазоне [0, 32767]. Чтобы получить равномерное распределение, и добавьте ведущие нули:
while a=$((RANDOM + 10000)); ((a <= 39999)); do :; done
a=${a#?}
Обратите внимание еще раз, что это не применимо везде, где безопасность является проблемой. Выход из $RANDOM
не непредсказуем.
Если вам нужна безопасность, то /dev/urandom
это правильное место для получения случайных данных. Вызов fold
не нужен на большинстве современных unice: вы можете получить 4 символа с помощью head -c
.
a=$(</dev/urandom tr -dc 0-9 | head -c 4)
head -c
не является POSIX и отсутствует в OpenBSD, но присутствует в других BSD и Linux (как с GNU coreutils, так и с BusyBox).
Если вам нужна переносимость на системы, в которых нет head -c
, то fold -w 4 | head -n 1
это хорошая замена, которая является стандартом POSIX. Просто отметьте, что вам нужен вызов head
, иначе fold
вы будете выводить строки из 4 цифр вечно.
решение2
fold
просто свернёт бесконечный поток цифр и, таким образом, a
будет определен бесконечно. Вам нужно будет добавить завершающую команду, простейшая head
:
a="$(tr -dc '[:digit:]' < /dev/urandom | fold -w 4 | head -n1)"
Просто сравните поведение этих двух команд.
tr -dc '[:digit:]' < /dev/urandom | fold -w 4
tr -dc '[:digit:]' < /dev/urandom | fold -w 4 | head -n1
Первый вариант покажет бесконечный поток 4-значных случайных чисел, а второй прервется после одной строки.