for 루프의 범위 변수에 대한 질문이 있습니다. for 루프에서는 {..}을 사용하여 범위를 정의할 수 있다는 것을 알고 있습니다. 하지만 저는 그것이 고객이 정의할 수 있기를 바랍니다. 따라서 스크립트에는 범위 값이 필요하며 이를 유연하게 사용하고 싶습니다. 이와 같이:
#!/bin/bash
while true;
do
echo "Some explenation..."
read -p "Possible values are: ALL or RANGE (to define a specific range):" answer
case $answer in
#ALL
[aA][lL][lL] )
echo "ALL is selected, 1 to 250"
RANGE="{1..250}"
break
;;
#RANGE
[rR][aA][nN][gG][eE] )
echo "Range is selected, please define a custom range. Notation should be like: <start>..<stop>"
echo "or: <single> <single>"
echo "or a combination of both. Like: 1..23 28 29 101..145 180 212"
read RANGE
break
;;
#OTHERS
* )
echo "Typo error!! Not correct, type again ALL, PRI, SEC or
RANGE"
;;
esac
done
echo ""
echo "Range for this execution is set to:"
echo "$RANGE"
for NEXI in $RANGE
do
sleep 0.2
echo "Nexus number: $NEXI"
done
echo ...
하지만 {1..10} 52 54 {120..128}을 입력하면 출력은 다음과 같습니다.
Nexus number: {1..10}
Nexus number: 52
Nexus number: 54
Nexus number: {120..128}
나는 그것이 다음과 같을 것으로 예상했지만 :
Nexus number: 1
Nexus number: 2
Nexus number: 3
Nexus number: 4
Nexus number: 5
Nexus number: 6
Nexus number: 7
Nexus number: 8
Nexus number: 9
Nexus number: 10
Nexus number: 52
Nexus number: 54
Nexus number: 120
Nexus number: 121
... etc.
완전히 작성되었습니다.
이 목표를 달성하기 위해 무엇을 바꿀 수 있나요?
감사해요.
답변1
문제는 중괄호 확장이 변수 확장보다 먼저 발생한다는 것입니다. 설명된 대로 man bash
:
확장 순서는 중괄호 확장, 매개변수 및 변수 확장, 산술 확장, 명령 대체(왼쪽에서 오른쪽으로 수행됨)입니다.
즉, $var
which contain {1..3}
및 do 와 같은 것이 있을 때 echo "$var"
쉘은 가능한 중괄호 확장을 찾습니다.앞으로변수를 해당 값으로 확장합니다. 중괄호가 변수 내부에 있으므로 이는 쉘이 이 시점에서 중괄호를 볼 수 없으므로 중괄호 확장이 수행되지 않음을 의미합니다.
eval
변수가 범위인 경우 한 가지 해결 방법은 이를 처리하는 것입니다. 루프 앞에 다음 줄을 추가합니다 for
.
if [[ $RANGE =~ ^[0-9]+\.\.[0-9]+$ ]]; then
RANGE=$(eval echo {$RANGE})
fi
이제 더 일반적으로는 쉘 스크립트에서 대문자 변수 이름을 사용하지 않는 것이 좋습니다. 환경 변수는 일반적으로 대문자로 표시되므로 정의된 환경 변수와 동일한 이름을 사용하는 경우 혼동을 일으킬 수 있습니다. 따라서 안전을 유지하려면 소문자 변수 이름을 사용하십시오.
게다가 이 프로그램은 디버깅하기 매우 귀찮고 사용하기에도 짜증나는 프로그램입니다. 런타임 시 사용자 입력을 요청하지 마세요! 대신 스크립트를 변경하고 매개변수를 허용하도록 만드세요. 값을 입력하는 것은 어렵고, 짜증나고, 오류가 발생하기 쉽고 자동화할 수 없습니다.
답변2
쉘을 다음으로 설정하면 ksh
이 코드가 작동합니다.
#!/usr/bin/ksh