OPTERR
나는 동작에 영향을 미치는 쉘 변수가 있는 getopts를 사용하고 있습니다 . OPTERR
getopts의 동작에 영향을 주기 위해 getopts의 값을 변경하고 같은 줄에서 getopts를 호출하고 싶지만 OPTERR
기본값으로 되돌리고 싶습니다. 따라서 변수 변경 명령 호출을 혼합하는 과정에 대해 약간 모호하다는 점을 고려하여 간단한 것을 시도해 볼까 생각했습니다 echo
. 이는 일련의 셸 명령과 그 출력으로, 그 중 일부는 나에게 이해가 되지 않습니다.
$ echo OPTERR
1
$ OPTERR=0 echo $OPTERR
1
지금은 여기서 멈추겠습니다. 두 번째 명령의 출력이 "0"이어야 하지 않나요? 그래서 이 질문을 하기 전에 나는 머리를 쥐어짜며 다음 명령이 서브셸에 있어야 하기 때문에 그럴 것이라고 생각했습니다. 그래서 시도해봤는데...
$ OPTERR=0 (echo $OPTERR)
-bash: syntax error near unexpected token `('
이것은 더욱 놀라운 일이다. 위 구성에 구문 오류가 있는 경우 서브쉘을 실행하기 위해 쉘 변수의 값을 어떻게 변경할 수 있습니까? (또한 echo 명령 뒤에 터미널 ";"을 넣으려고 시도했지만 동일한 결과를 얻었습니다.) 나도 시도해 봤는데...
$OPTERR=0 bash -c 'echo $OPTERR'
1
그러므로 거기에도 기쁨이 없습니다. 다른 방법을 택했는데..
$function sf() { echo $OPTERR }
$sf
1
$OPTERR=0 sf
0
$sf
1
성공! ! 그런데 왜? 이 기능은 특히 서브쉘이 아니며(그렇다고 생각하지 않습니다), 이는 실제로 제가 원하는 것이 아닙니다(비록 내 응용 프로그램에서 작동하도록 만들 수는 있지만). 작동하는 또 다른 공식은 다음과 같습니다.
$function sf() { (OPTERR=0; echo $OPTERR;) }
$sf
0
$echo $OPTERR
1
이것은 내가 원하는 것과 매우 유사하지만 물론 실제 스크립트(내가 사소하지는 않음 ) 는 echo
이를 수행하도록 의도되었으며 나머지 스크립트에서 볼 수 있는 변수를 변경해야 합니다. 그래서 간단한 스크립트를 다음과 같은 간단한 변수 세트로 변경했습니다.getopts
getopts
echo
$function sf() { foo='bar'; (foo='check'; echo $foo;); echo $foo; }
$sf
check
bar
오! ! 그래서 getopts
내가 원하는 환경으로 호출을 할 수는 있는데, 서브쉘에서는 어떤 값도 얻을 수 없습니다. 나는 여기에 나열하기에는 너무 당황스러운 foo 및 모든 종류의 항목을 내보내려고 시도했지만 여기에 내 문제가 있습니다. 내 모든 실험을 종합하면 이 모든 것이 어떻게 작동해야 하는지에 대한 근본적으로 잘못된 모델이 드러날 것입니다. 내 이해에 무엇이 빠졌습니까? 올바른 접근 방식은 무엇입니까?
다시 한번 말씀드리지만, 제가 하고 싶은 것은 with 를 사용하여 0으로 설정되는 함수를 만드는 것입니다 getopts
. OPTERR
이상적으로는 함수가 호출되는 줄에 설정하지 않고 OPTERR
함수 외부에서 복원되도록 설정하는 것입니다. 대부분의 OPTERR
중요한 것은 실제로 처리할 수 있는 방식으로 getopts
문제가 많은 것처럼 들리지만 꽤 합리적이며 OPTERR
이 변수의 존재는 그것이 가능해야 함을 시사합니다.
답변1
$ echo $VAR
$VAR
이는 쉘이 명령줄에서 확장한 후에만 변수 할당을 적용하기 때문에 이전 값을 제공합니다 .
IFS= read -r foo
그러나 웹사이트에서 자주 볼 수 있는 구성은 명령줄에서 가져오는 read
대신 내부적으로 사용하기 때문에 작동합니다. IFS
마찬가지로 OPTERR=0 getopts ...
작동해야 합니다.
$ cat arg.sh
#!/bin/bash
OPTERR=0 getopts a:b var
echo "var: $var OPTERR: $OPTERR"
$ bash arg.sh -z
var: ? OPTERR: 1
옵션이 유효하지 않은 경우에도 -z
오류 메시지가 나타나지 않습니다.
$ OPTERR=0 bash -c 'echo $OPTERR'
특별하기 때문에 좀 특별해요 OPTERR
. Bash 매뉴얼 페이지는 다음과 같이 말합니다.
OPTERR
값으로 설정하면1
Bash는 내장 명령에 의해 생성된 오류 메시지를 표시합니다getopts
.OPTERR
쉘이 호출되거나 쉘 스크립트가 실행될 때마다 1로 초기화됩니다.
하지만 아이디어는 정확하며 일반 변수와 함께 작동합니다.
$ FOO=123 bash -c 'echo $FOO'
123
내가 하고 싶은 것은 다음을 사용하는 함수를 만드는 것입니다.
getopts
함수의 인수를 구문 분석하고 이를 기본 프로그램(예: dothis -a; dothis -b -c
)에서 여러 번 호출하고 해당 함수를 사용하여 셸의 인수( )를 구문 분석하지 않는 경우 변수도 수정해야 한다는 점 parse_args "$@"
을 기억해야 합니다 . 또한 해당 기능에 맞게 현지화해야 합니다.getopts
OPTIND
예를 들어, 여기에서 두 번째 함수 호출에는 옵션이 표시되지 않습니다.
foo() { while getopts "abcd" opt; do echo "$opt"; done; };
foo -a -a
foo -b -b
이전 기능과 결합하면 이 기능은 자동으로 작동합니다.
foo() {
local OPTIND=1
while OPTERR=0 getopts "abcd" opt; do
echo "$opt"
done
}
답변2
함수 호출 중에 OPTERR을 0으로 설정해야 하는 경우 Gordon Davisson이 제안한 대로 이를 로컬 변수로 설정하세요.
#!/bin/bash
myfunc() {
local OPTERR=0
printf "Inside myfunc, OPTERR=%d\n" "$OPTERR"
while getopts ":a:" opt; do
echo $opt is $OPTARG
done
}
printf "Before calling myfunc, OPTERR=%d\n" "$OPTERR"
myfunc
printf "After calling myfunc, OPTERR=%d\n" "$OPTERR"
결과 :
Before calling myfunc, OPTERR=1
Inside myfunc, OPTERR=0
After calling myfunc, OPTERR=1