Arrays 如何在声明的数组中使用RANDOM命令

Arrays 如何在声明的数组中使用RANDOM命令,arrays,bash,password-generator,Arrays,Bash,Password Generator,我正在尝试构建一个脚本,其中需要使用以下参数创建密码生成器: 长度必须至少为8个字符,但不得超过16个字符 必须至少包含1位数字(0-9) 必须包含至少1个小写字母 必须至少包含1个大写字母 必须仅包含一个@$%&*+-= 我有两个想法: 第一: #!/bin/bash # #Password Generator # # Upper=('A''B''C''D''E''F''G''H''I''J'K''L''M''N''O''P''Q''R''S''T''U''V''W''X''Y''Z

我正在尝试构建一个脚本,其中需要使用以下参数创建密码生成器:

  • 长度必须至少为8个字符,但不得超过16个字符
  • 必须至少包含1位数字(0-9)
  • 必须包含至少1个小写字母
  • 必须至少包含1个大写字母
  • 必须仅包含一个
    @$%&*+-=

我有两个想法:

第一:

#!/bin/bash
#
#Password Generator 
#
#

Upper=('A''B''C''D''E''F''G''H''I''J'K''L''M''N''O''P''Q''R''S''T''U''V''W''X''Y''Z')
Lower=('a''b''c''d''e''z''f''g''h''i''j''k''l''m''o'''p''q''r''s''t''u''v''w''x''y''z')
Numbers=('1''2''3''4''5''6''7''8''9')
SpecialChar=('@''#''$''%''&''*''+''-''=')



if [ S# -eq 0 ] ; then 


Pwlength=`shuf -i 8-16 -n 1` 

Password=`< /dev/urandom tr -dc A-Za-z0-9$SpecialChar | head -c $Pwlength` 

echo "Random Password is being generated for you"

sleep 5

echo "Your new password  is : $Password"


exit
#/bin/bash
#
#密码生成器
#
#
上部=(“A”“B”“C”“D”“E”“F”“G”“H”“I”“J”“K”“L”“M”“N”“O”“P”“Q”“R”“T”“V”“W”“X”“Y”“Z”)
较低=(“a”“b”“c”“d”“e”“z”“f”“h”“i”“j”“k”“l”“m”“o”“p”“q”“r”“t”“v”“w”“x”“y”“z”)
数字=('1''2''3''4''5''6''7''8''9')
特殊字符=(“@”#“$”%&“*”+“-”=”)
如果[S#-eq 0];然后
Pwlength=`shuf-i8-16-n1`
密码=`
问题是我得到了我甚至没有定义的字符

第二个合理的想法是:

for((i=0;i<4;i++)) 

do

password=${Upper[$random % ${#Lower[@]} ] }
password=${Upper[$random % ${#Upper[@]} ] }
password=${Upper[$random % ${#Number[@]} ] }
password=${Upper[$random % ${#SpecialChar[@]} ] }

done

for((i=0;i在您的第一个示例中,将“-”字符移动到SpecialChar的末尾。我认为您的定义导致允许“+”到“=”(即,传递给tr的值读取为“+-=”,这说明了您不希望看到的字符。或者,将“-”替换为“\ux”


您的第一次尝试出现以下问题:

  • 您正在使用数组来包含单个字符串。粘贴
    'A''B''C'
    相当于
    'ABC'
    。简单地将它们转换为标量变量可能是最简单的修复方法
  • 你不是
  • 您声明了
    上限
    下限
    数字
    ,但从不使用它们
  • 对于只使用过一次(或更少:-)的东西使用变量是值得怀疑的
  • 正如@KevinO所指出的,破折号在
    tr
    中有一个特殊的含义,如果你想从字面上匹配破折号,破折号必须是第一个或最后一个
除此之外,
sleep 5
似乎没有任何用处,如果还没有,它会开始让你烦恼。如果你真的想要一台速度较慢的电脑,我相信这里有人愿意交易

您的第二次尝试出现以下问题:

  • Bash中的特殊变量
    $RANDOM
    以大写字母拼写
  • 您正在尝试对未定义好的字符数组(无引号!)执行模运算。
    %
    之后的除数需要是单个整数。您可以将字符代码转换为整数,但这有点痛苦,而且还不清楚您希望得到什么样的结果
快速尝试修复第一次尝试将是

Password=$(< /dev/urandom tr -dc 'A-Za-z0-9@#$%&*+=-' | head -c $(shuf -i 8-16 -n 1))
Password=$(
如果要验证生成的密码的某些属性,我仍然不明白为什么需要数组

while read -r category expression; do
    case $Password in
      *[$expression]*) continue;;
      *) echo "No $category"; break;;
    esac
done <<'____HERE'
    lowercase a-z
    uppercase A-Z
    numbers   0-9
    specials  -@#$%&*+=
HERE
while read-r类别表达式;do
案例$Password in
*[$expression]*)继续;;
*)echo“无$category”;打破
以撒
完成
  • 如前所述,直接使用字符串来处理字符列表会更简洁、更容易。处理数组中的特殊字符可能会产生副作用(例如,使用“*”字符获取当前目录中的文件列表)。此外,数组可能很难作为函数参数传递

  • 您可以从小写生成大写

    ALPHA_UP="`echo \"$ALPHA_LOW\" | tr '[:lower:]' '[:upper:]'`"
    
  • 包含随机数的变量是
    $random
    (大写)

  • sleep 5
    是不必要的

  • 您需要找到一种方法来保持每种字符类型的剩余出现次数。为了获得更多信息,我编写了一个完整的脚本来完成您描述的操作


它是
$RANDOM
,而不是
$RANDOM
$SpecialChar
不会扩展到数组的内容
“${SpecialChar[@]}”
,因为它包含shell元字符,所以需要像我所展示的那样对其进行双引号引用,以便shell不会对这些元字符做出反应(展开任何通配符匹配,等等).说真的,
sleep5
的意义是什么?不管怎样,使用单个字符串的数组是毫无意义的。在删除引号后,
'A'B'C'
相当于
'ABC'
:~/bin>UPPER=(“A”“B”“C”“D”“E”“F”“G”“H”“I”“J”“K”“L”“M”“N”“O”“P”“Q”“R”“S”“T”“U”“V”“W”“X”“Y”“Z”)关于特殊字符位置,您是对的。我做了一个改变,现在起作用了。关于另一种方法,我想了解我必须引用的部分是什么?password=“${Upper[$random%${#Upper[@]}”]}我想使用random混合数组中的字符,并给我一个字符,该字符将添加到“password”中变量我必须使它在a中的所有数组中运行四次,这样我就可以有16个字符我声明一个数组,因为以后我必须对密码使用它来验证密码规则,因此在初始化时,各个元素之间需要空格。您的代码没有显示如何尝试使用数组,因此很遗憾,我无法告诉您如何修复这部分代码
tr
在任何情况下都需要一个字符串。如果您当前的代码使用数组,它实际上不会使用,并且将其转换为使用常规标量可能仍然是最简单的修复方法。我已经为整个脚本打开了另一篇文章
ALPHA_LOW="abcdefghijklmnopqrstuvwxyz"

# Then simply access the char in the string at the ith position
CHAR=${ALPHA_LOW:$i:1}
ALPHA_UP="`echo \"$ALPHA_LOW\" | tr '[:lower:]' '[:upper:]'`"