나는 Linux를 매우 쉽게 설정할 수 있도록 몇 가지 스크립트 세트를 작성했습니다. 그래서 저는 이 스크립트를 별도의 함수로 만들어 모두 하나의 스크립트에 넣었습니다. 사용자가 숫자 중 하나를 입력하면 함수가 호출되도록 숫자를 설정했습니다. 그러나 사용자가 숫자를 입력하면 스크립트는 모든 함수를 호출합니다.
n=1
#note you need spaces between [ ]
while [ $n == 1 ]
do
echo "Base install=1"
echo "Mintrepos=2"
echo "Asusn13 driver=3"
echo "Install Standard openbox=4"
echo "Install Xfceopenbox=5"
echo "backing up standard open box config=6"
echo "backing up openboxfce=7"
echo
read choice
if [ "$choice"==1 ]
then
baseinstall
fi
if [ "$choice"==2 ]
then
linuxmintrepos
fi
if [ "$choice"==3 ]
then
asusn13driver
fi
if [ "$choice"==4 ]
then
standardopenbox
fi
if [ "$choice"==5 ]
then
xfceopenbox
fi
if [ "$choice"==6 ]
then
backupstandopenbox
fi
if [ "$choice"==7 ]
then
backupxfc4openbox
fi
echo "You installed: "
if [ "$choice"==1 ]
then
echo "baseinstall"
fi
if [ "$choice"==2 ]
then
echo "linuxmintrepos"
fi
if [ "$choice"==3 ]
then
echo asusn13driver
fi
if [ "$choice"==4 ]
then
echo "standardopenbox"
fi
if [ "$choice"==5 ]
then
echo "xfceopenbox"
fi
if [ "$choice"==6 ]
then
echo "backupstandopenbox"
fi
if [ "$choice"==7 ]
then
echo "backupxfc4openbox"
echo "If you would like to keep going, type in 1, if not, type in any other number"
read n
fi
done
답변1
바꾸다:
if [ "$choice"==1 ]
그리고:
if [ "$choice" = 1 ]
모든 후속 테스트에 대해 동일한 작업을 수행합니다.
설명하다
쉘이 이를 볼 때 "$choice"==1
문자열을 봅니다. 예를 들어, choice
2이면 문자열이 표시됩니다 2==1
. 이것은 평등 테스트가 아닙니다. 문자열입니다. 비어 있지 않은 문자열이므로 테스트는 true를 반환합니다. 따라서 모든 선택이 실행됩니다.
동등성 테스트를 인식하려면 공백이 필요합니다.
또한 작은 점으로 [
스타일 테스트의 경우 등호는 입니다 =
. bash는 이를 허용 ==
하지만 올바르지 않으며 다른 쉘에서는 작동하지 않습니다.
[...]
명령줄에서 테스트 살펴보기
[
명령줄에서 테스트가 작동하는 방식을 쉽게 탐색할 수 있습니다. 먼저, 빈 문자열이 false로 테스트된다는 것을 보여드리겠습니다.
$ if [ "" ]; then echo True; else echo False; fi
False
비어 있지 않은 문자열은 무엇이든 참입니다:
$ if [ abc ]; then echo True; else echo False; fi
True
이제 살펴보겠습니다 2==1
.
$ if [ 2==1 ]; then echo True; else echo False; fi
True
2==1
비어 있지 않은 문자열이므로 테스트는 true입니다 .
이제 공백을 추가하고 동등성을 테스트해 보겠습니다.
$ if [ 2 = 1 ]; then echo True; else echo False; fi
False
$ if [ 2 = 2 ]; then echo True; else echo False; fi
True
좀 더 미묘하게 말하자면, =
여기서는 문자열 동일성 테스트가 제대로 작동합니다. 수치 동등성을 테스트하려면 대신 를 사용하십시오 -eq
.
$ if [ 2 -eq 2 ]; then echo True; else echo False; fi
True
답변2
다른 사람들이 언급했듯이 귀하의 if test ...;fi
진술은 문법적으로 정확하지 않지만 전체 접근 방식이 약간 조잡하다는 점은 주목할 가치가 있습니다. 이 스크립트 흐름에는 크게 개선할 수 있는 여러 측면이 있습니다. 특히 나중에 읽고 편집하기가 더 쉬울 것입니다.
첫째, 루프 set
에서 반복적으로 선택할 수 있습니다 for
. 그래서 가능한선택하다해당 선택자는 사용자에게 알리고 자동으로 생성되지만 스크립트에서는 이를 모두 문자열 목록에 넣을 수 있으므로 걱정할 필요가 없습니다.
set --
for c in \
"Base install:base_fn" \
"Mintrepos:mint_fn" \
"Asusn13 driver:asus_fn" \
"Install Standard openbox:std_obox_fn" \
"Install Xfceopenbox:xfce_obox_fn" \
"backing up standard open box config:bkup_fn obox" \
"backing up openboxfce:bkup_fn xfce"
do
set -- "$@" "${c##*:}"
printf "'%s' = $#\n" "${c%:*}"
done
이는 호출을 fn_name
위치 인수 배열로 인코딩하는 동시에 사용자에게 친숙한 설명을 표준 출력으로 인쇄합니다.
선택 목록을 작성 "$@"
하고 진행 상황을 인쇄한 후에는 read
여러 번의 시도 실패 후 종료되는 작은 루프에서 사용자 선택을 수행하는 동시에 입력의 유효성을 검사할 수 있습니다.
chk=$((($#<1)*5)) #if not at least one choice quit
until [ "$((chk+=1))" -gt 5 ] && exit 1 #chks up to 5 times or quits
printf '\nSelect: ' #prompts for each try
read -r c && [ -n "${c##*[!0-9]*}" ] #fails if input not number or empty
do echo "Invalid selection."; done #prints a notice and retries
shift
마지막으로 불필요한 매개변수를 제거하고 다음을 호출 할 수 있습니다 $1
.
shift "$((c-1))"; $1
앞에 0이 없는지 확인하는 것이 가장 좋습니다. shift
사용자가 너무 높은 숫자를 선택하면 오류가 발생합니다.
[ "$((c=$(printf %.d "$c")))" -gt 0 ] || exit
shift "$((c-1))" && $1
이것은 위치 배열을 매우 유용하게 만드는 숫자 선택 목록용입니다. 보다 일반적으로 다음 case
문을 사용할 수 있습니다.
case "$choice" in
(pattern 1) do as necessary for a match;;
(pattern 2) do otherwise for this match;;
(pattern 3) continue this wise for each;;
(*) until there isn't a match ;;
esac
이는 많은 쉘을 에뮬레이트하는 이식 가능한 방법일 뿐입니다.(포함하다 bash
)수년 전에 select
소개된 진술이 제공될 것입니다.ksh
에서 man bash
:
select
이름[in
단어];do
목록;done
- 뒤에 오는 단어 목록이 확장되어 항목 목록이 생성됩니다. 확장된 단어 세트는 표준 오류로 인쇄되며 각 단어 앞에는 숫자가 붙습니다. 만약에연설에서생략된 위치 매개변수(또는
"$@"
)인쇄됩니다(아래 매개변수 참조). 그런 다음 프롬프트가 표시$PS3
되고 표준 입력에서 한 줄을 읽습니다.
- 뒤에 오는 단어 목록이 확장되어 항목 목록이 생성됩니다. 확장된 단어 세트는 표준 오류로 인쇄되며 각 단어 앞에는 숫자가 붙습니다. 만약에연설에서생략된 위치 매개변수(또는
답변3
에 있어야 합니다 ==
. 그렇지 않으면 문자열 과 비교하는 대신 "$choice"==1
문자열 자체를 전달 하게 됩니다 . 문자열이 수신 되면 문자열이 비어 있지 않은 한 true로 평가됩니다.if
$choice
1
[
$ foo="bar"; [ $foo ] && echo true
true
$ foo=""; [ "$foo" ] && echo true ## echoes nothing
대괄호 외부에 test
공백이 없으면 변수는 실제로 에 할당됩니다 =1
. 표시하려면:
$ f==3
$ echo $f
=3
$ [ 10==12 ] && echo yes
yes
위에서 볼 수 있듯이 f==3
변수 $f
를 =3
.
따라서 if
블록에서 테스트되는 것은 항상 true로 평가되고 실행되는 비어 있지 않은 문자열입니다 if
. 이것은 작동합니다:
if [ "$choice" == "1" ]
then
baseinstall
fi
대안 으로 =
또는==
문자열 비교배쉬에서. 산술 비교를 원합니다.
if [ "$choice" -eq "1" ]
then
baseinstall
fi