从某个项目获得的:
generatePassword() {
# 获取生成长度
local length="$1"
# 12<=$length<=128 否则赋值 length=20
[[ $length -ge 12 && $length -le 128 ]] || length=20
# ${#genpassword}获取字符串长度。
# $genpassword长度<($length-1) || $special是否为空(特殊字符)
while [[ ${#genpassword} -lt $((length-1)) || -z $special ]]; do
# head -c1 /dev/urandom 从文件开头获取一个字符
# tr -dc 不符合的字符全部删除
newchar=$(head -c1 /dev/urandom | tr -dc '0-9a-zA-Z!#$%&()*+,-./:;<=>?@[]^_{|}~')
# -n 不为空
if [[ -n $(echo $newchar | tr -dc '!#$%&()*+,-./:;<=>?@[]^_{|}~') ]]; then
special=${newchar}
elif [[ ${#genpassword} -lt $((length-1)) ]]; then
genpassword=${genpassword}${newchar}
fi
done
# 9$(date +%N) seems weird but it's important because date may return
# a leading 0 causing modulo to fail on reading it as octal number
position=$(( 9$(date +%N) % $length ))
# inject the special character at a random position
# ${var:0:5} 字符串截取,从0开始截取5个
echo ${genpassword::($position)}$special${genpassword:($position)}
}