if 条件出错

if 条件出错

我只是检查密码是否包含小写字母和大写字母,我在第 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 -rin 来读取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]

shshell 中,您可以这样编写脚本:

#!/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 ]]

相关内容