我只是检查密码是否包含小写字母和大写字母,我在第 19 行收到错误。
myscript.sh
:
#!bin/sh
read password
conditionarr=(0 0)
if [[ $password =~ [A-Z] ]]
then
condtionarr[1]=1
fi
if [[ $password =~ [a-z] ]]
then
conditionarr[0]=1
fi
if [ ${conditionarr[0]} == 1 || ${conditionarr[1]} == 1 ]
then
printf "%s" "Yes\n "
else
printf "%s" "No\n"
fi
错误:
./myscript.sh: line 19: [: missing `]'
./myscript.sh: line 19: 0: command not found
这段代码有什么问题?谁能告诉我如何解决这个问题?
答案1
您的代码中有几个问题:
-行
#!
应该读取(或者解释器或系统#!/bin/bash
的完整绝对路径)。bash
请注意,您使用的 shell 代码需要使用bash
,因此将#!
-line 指向sh
解释器是不正确的,因为该 shell 可能无法理解非标准[[ ... ]]
或数组的使用等内容。密码可能应该使用
IFS= read -s -r
in 来读取bash
,以避免回显终端的输入,并允许毫无问题地使用\
,并允许侧翼空格等。最好写多个测试
[ ... ] || [ ... ]
。这就是导致您实际错误消息的原因。该[
实用程序不知道||
.
建议:
#!/bin/bash
IFS= read -p 'Enter password: ' -sr password
check=(0 0)
[[ $password =~ [A-Z] ]] && check[0]=1
[[ $password =~ [a-z] ]] && check[1]=1
if [ "${check[0]}" = 1 ] || [ "${check[1]}" = 1 ]; then
echo yes
else
echo no
fi
或者,不再需要数组:
#!/bin/bash
IFS= read -p 'Enter password: ' -sr password
if [[ $password =~ [A-Z] ]] ||
[[ $password =~ [a-z] ]]
then
echo yes
else
echo no
fi
请注意,测试$password
字符串是否匹配[A-Z]
或者对于 的匹配[a-z]
可以在一次测试中完成[A-Za-z]
。
在sh
shell 中,您可以这样编写脚本:
#!/bin/sh
printf 'Enter password: ' >&2
state=$(stty -g) # save stty state
stty -echo # turn off local echo
IFS= read -r password
stty "$state" # reset stty state to original
case $password in
*[A-Za-z]*)
echo yes
;;
*)
echo no
esac
请注意,我已将大写和小写字符的测试合并到一个测试中,并且使用的模式case
是 shell 通配模式,而不是正则表达式。
如果您需要检查上层和小写字母,您仍然需要两个单独的测试:
case $password in (*[A-Z]*) check1=true;; (*) check1=false; esac
case $password in (*[a-z]*) check2=true;; (*) check2=false; esac
if "$check1" && "$check2"; then
echo yes
else
echo no
fi
答案2
请注意您如何从最后一个条件切换到[[
到:[
if [[ $password =~ [a-z] ]] if [ ${conditionarr[0]} == 1 || ${conditionarr[1]} == 1 ]
两者之间有一个很大的区别,即 that[[
是一个特殊的 shell 结构,并且有自己的语法,而 while[
只是一个常规命令。
看:
在 中[ ${conditionarr[0]} == 1 || ...
,||
终止命令,因此运行的只是[ whatever == 1
。但[
希望将 a]
作为最后一个参数,以便该命令看起来更好。现在没有了,所以它抱怨。 (同样[
,您应该引用变量扩展所有常见的原因,并使用=
代替==
,因为后者不是标准的。)
您可以使用其中任何一个
if [ "${conditionarr[0]}" = 1 ] || [ "${conditionarr[1]}" = 1 ]
# or
if test "${conditionarr[0]}" = 1 || test "${conditionarr[1]}" = 1
但切换到它会更容易[[
,因为它确实支持||
其中,并且实际上缺少引用更安全(无论如何在左侧==
):
if [[ ${conditionarr[0]} == 1 || ${conditionarr[1]} == 1 ]]