script.sh
다음과 같은 쉘 스크립트가 있습니다.
names=( jack john jerry)
사용자가 다음과 같이 첫 번째 인수로 이 세 가지 이름 중 하나를 입력하기를 원합니다.
./script.sh jack
예를 들어 사용자가 문자를 잘못 입력한 경우
./script.sh kate
이는 a를 실행 exit
하고 사용자에게 이 3개 중 하나만 입력하도록 요청합니다.
어떻게 해야 합니까?
답변1
names=(jack john jerry);
if [[ " "${names[@]}" " == *" "$1" "* ]] ;then
echo "$1: ok"
else
echo "$1: not recognized. Valid names are:"
echo "${names[@]/%/,}"
exit 1
fi
위의 코드는 공백을 포함하지 않는 이름에 작동합니다.
아래 수정된 버전은 이름의 공백을 처리합니다.
names=("flash jack" john jerry);
d=$'\1' # validation delimiter - value is \x01
valid="${names[@]/%/$d}"
valid="$d${valid//$d /$d}"
if [[ $valid == *$d$1$d* ]] ;then
echo "$1: ok"
else
echo "$1: not recognized. Valid names are:"
echo "${names[@]/%/,}"
exit 1
fi
공백 인식 버전의 출력:
flash jack: ok
또는
kate: not recognized. Valid names are:
flash jack, john, jerry,
답변2
이것이 바로 case
선언의 목적입니다:
#! /bin/bash
case $1 in
[Jj]ack)
echo "You chose Jack!"
;;
[Jj]ohn)
echo "You chose John!"
;;
[Jj]erry)
echo "You chose Jerry!"
;;
## For all other cases
*)
echo 'Please choose one of "John", "Jack" or "Jerry"' >&2
exit 1
esac
$1
Case 문은 스크립트에 전달된 첫 번째 인수 값을 기반으로 실행됩니다. jack
또는 이면 Jack
첫 번째 선택이 실행되고, 또는이면 John
두 john
번째 선택이 실행됩니다. 다른 항목을 입력하면 마지막 문이 실행됩니다.
답변3
먼저, 충분히 강력한 쉘 스크립트는 악마의 작업으로 간주될 수 있는 괴물 같은 배열 구현을 사용할 수 있다는 점을 언급해야 합니다. 또한 어떤 쉘인지 표시하지 않았지만 bash라고 가정합니다.
이를 수행하는 방법에는 여러 가지가 있지만 모두 보기 흉합니다.
1) 배열을 반복합니다. 읽기 쉽고 비교적 깨끗하지만 비효율적입니다.
for i in 0 1 2 3 4
do
echo compare ${ARRAY[$i]} perhaps using test or whatever you like
done
2) 한 번에 모든 작업을 수행하려면 expr을 사용하십시오. 이는 깨지기 쉬우며 한 이름이 다른 이름의 하위 문자열인 경우 깨집니다. 이 문제는 해결될 수 있지만, 이 경우 더 나은 도구를 사용하는 것이 좋습니다.
$ ARRAY=(jack john jerry )
$ expr "${ARRAY[*]}" : '.*jack.*'
15 # it's found
$ expr "${ARRAY[*]}" : '.*sue.*'
0 # not found
여기서 jack 또는 sue는 $1 또는 확인하려는 매개변수로 대체됩니다.