如何在Bash中生成一个范围内的随机数?
当前回答
生成随机的3位数字
这对于创建示例数据非常有用。示例:将所有测试数据放在名为“test-create-volume-123”的目录中,然后在测试完成后,删除整个目录。通过生成恰好三个数字,就不会有奇怪的排序问题。
printf '%02d\n' $((1 + RANDOM % 100))
这是按比例缩小的,例如到一个数字:
printf '%01d\n' $((1 + RANDOM % 10))
它可以放大,但只能放大到四位数。原因见上文:)
其他回答
0到9之间的随机数。
echo $((RANDOM%10))
这是我写的一个函数,它将输出一个期望范围>的随机数
描述:
随机<min> <max> 生成一个从最小到最大的随机数。最小值和最大值都可以 正数或负数,生成的随机数也可以是负数,所以 只要范围(max - min + 1)小于或等于32767。Max必须是>= min。
它的核心是:
random() {
min="$1"
max="$2"
range=$((max - min + 1))
rand=$((min + (RANDOM % range)))
echo "$rand"
}
用法:
# general form: obtain a random number between min and max, inclusive
random <min> <max>
# Example: obtain a random number from -10 to 10, inclusive
random -10 10
这是从bash内置变量RANDOM中工作的,它可能只在底层使用C rand(),因为它们的最大值都是32767——请参阅:
https://en.cppreference.com/w/c/numeric/random/rand https://en.cppreference.com/w/c/numeric/random/RAND_MAX
有关bash文档,请参阅man bash:
随机 每次引用此参数时,都会生成一个0到32767之间的随机整数。随机数序列可以通过赋值给random来初始化。如果RANDOM未被设置,它将失去其特殊属性,即使随后被重置。
健壮的、可运行的、可源代码的脚本版本
这是上面随机函数的一个更健壮的版本。它包括完整的错误检查,边界检查,通过random——help或random -h提供的帮助菜单,以及一个特殊的run_check功能,允许您源或运行此脚本,以便您可以源它以将随机函数导入任何其他脚本——就像您在Python中所做的一样!
random.sh <——点击这个链接总是从我的eRCaGuy_dotfiles repo中获得最新版本。
RETURN_CODE_SUCCESS=0
RETURN_CODE_ERROR=1
HELP_STR="\
Generate a random integer number according to the usage styles below.
USAGE STYLES:
'random'
Generate a random number from 0 to 32767, inclusive (same as bash variable 'RANDOM').
'random <max>'
Generate a random number from 0 to 'max', inclusive.
'random <min> <max>'
Generate a random number from 'min' to 'max', inclusive. Both 'min' and 'max' can be
positive OR negative numbers, and the generated random number can be negative too, so
long as the range (max - min + 1) is less than or equal to 32767. Max must be >= min.
This file is part of eRCaGuy_dotfiles: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles
"
print_help() {
echo "$HELP_STR" | less -RFX
}
# Get a random number according to the usage styles above.
# See also `utils_rand()` in utilities.c:
# https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/c/utilities.c#L176
random() {
# PARSE ARGUMENTS
# help menu
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
print_help
exit $RETURN_CODE_SUCCESS
fi
# 'random'
if [ $# -eq 0 ]; then
min=0
max="none"
# 'random max'
elif [ $# -eq 1 ]; then
min=0
max="$1"
# 'random min max'
elif [ $# -eq 2 ]; then
min="$1"
max="$2"
else
echo "ERROR: too many arguments."
exit "$RETURN_CODE_ERROR"
fi
# CHECK FOR ERRORS
if [ "$max" = "none" ]; then
rand="$RANDOM"
echo "$rand"
exit "$RETURN_CODE_SUCCESS"
fi
if [ "$max" -lt "$min" ]; then
echo "ERROR: max ($max) < min ($min). Max must be >= min."
exit "$RETURN_CODE_ERROR"
fi
# CALCULATE THE RANDOM NUMBER
# See `man bash` and search for `RANDOM`. This is a limitation of that value.
RAND_MAX=32767
range=$((max - min + 1))
if [ "$range" -gt "$RAND_MAX" ]; then
echo "ERROR: the range (max - min + 1) is too large. Max allowed = $RAND_MAX, but actual" \
"range = ($max - $min + 1) = $range."
exit "$RETURN_CODE_ERROR"
fi
# NB: `RANDOM` is a bash built-in variable. See `man bash`, and also here:
# https://stackoverflow.com/a/1195035/4561887
rand=$((min + (RANDOM % range)))
echo "$rand"
}
# Set the global variable `run` to "true" if the script is being **executed** (not sourced) and
# `main` should run, and set `run` to "false" otherwise. One might source this script but intend
# NOT to run it if they wanted to import functions from the script.
# See:
# 1. *****https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/bash/argument_parsing__3_advanced__gen_prog_template.sh
# 1. my answer: https://stackoverflow.com/a/70662049/4561887
# 1. https://github.com/ElectricRCAircraftGuy/eRCaGuy_hello_world/blob/master/bash/check_if_sourced_or_executed.sh
run_check() {
# This is akin to `if __name__ == "__main__":` in Python.
if [ "${FUNCNAME[-1]}" == "main" ]; then
# This script is being EXECUTED, not sourced
run="true"
fi
}
# ----------------------------------------------------------------------------------------------------------------------
# Main program entry point
# ----------------------------------------------------------------------------------------------------------------------
# Only run main function if this file is being executed, NOT sourced.
run="false"
run_check
if [ "$run" == "true" ]; then
random "$@"
fi
想使用不带dd和od的/dev/urandom
function roll() { local modulus=${1:-6}; echo $(( 1 + 0x$(env LC_CTYPE=C tr -dc '0-9a-fA-F' < /dev/urandom | head -c5 ) % $modulus )); }
测试
$ roll
5
$ roll 12
12
它有多随机?
$ (echo "count roll percentage"; i=0; while [ $i -lt 10000 ]; do roll; i=$((i+1)); done | sort | uniq -c | awk '{print $0,($1/10000*100)"%"}') | column -t
count roll percentage
1625 1 16.25%
1665 2 16.65%
1646 3 16.46%
1720 4 17.2%
1694 5 16.94%
1650 6 16.5%
还可以使用shuf(可在coreutils中使用)。
shuf -i 1-100000 -n 1
bash 5.1引入了一个新变量SRANDOM,它从系统的熵引擎中获取随机数据,因此它不是线性的,不能重新种子以获得相同的随机序列。这个变量可以用来代替RANDOM来生成更多的随机数。
$ echo $((1 + SRANDOM % 10))
4