조건 오류인 경우

조건 오류인 경우

방금 비밀번호에 소문자와 대문자가 포함되어 있는지 확인했는데 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사용 중인 쉘 코드에는 가 ​​필요하므로 bash쉘 이 비표준 또는 배열 사용법과 같은 것을 이해하지 못할 수 있으므로 인터프리터 #!에 -line을 지정하는 것은 올바르지 않습니다.sh[[ ... ]]

  • 터미널의 입력이 에코되는 것을 방지하고 문제 없이 사용할 수 있으며 측면 공백 등을 허용하려면 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].

sh쉘 에서는 다음과 같이 스크립트를 작성할 수 있습니다.

#!/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정규식이 아닌 쉘 글로빙 패턴입니다.

상위 레벨을 확인해야 하는 경우그리고소문자인 경우에도 두 가지 별도의 테스트가 필요합니다.

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 ]

둘 사이에는 큰 차이가 있습니다. 즉, [[특별한 쉘 구조로 자체 구문을 갖고 있는 반면 while은 [일반 명령이라는 점입니다.

바라보다:

에서는 명령이 종료되므로 실행 중인 것은 모두 [ ${conditionarr[0]} == 1 || ...입니다 . 그러나 명령이 더 보기 좋게 보이도록 마지막 매개변수로 a를 갖고 싶습니다 . 이제는 그렇지 않아서 불평합니다. (다시 말하지만 , 변수 확장을 인용해야 합니다.||[ whatever == 1[][모든 일반적인 이유, =대신 사용하십시오 ==. 후자가 표준이 아니기 때문입니다. )

다음 중 하나를 사용할 수 있습니다.

if [    "${conditionarr[0]}" = 1 ] || [    "${conditionarr[1]}" = 1 ]
# or
if test "${conditionarr[0]}" = 1   || test "${conditionarr[1]}" = 1

[[그러나 지원하기 때문에 전환하기가 더 쉬울 것이며 ||참조가 누락되어도 실제로 더 안전합니다(어쨌든 왼쪽에 있음 ==).

if [[ ${conditionarr[0]} == 1 || ${conditionarr[1]} == 1 ]]

관련 정보