방금 비밀번호에 소문자와 대문자가 포함되어 있는지 확인했는데 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 -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
쉘 에서는 다음과 같이 스크립트를 작성할 수 있습니다.
#!/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 ]]