
기능이 있는데 그 pipefail
안에 있는 옵션을 사용하고 싶어요. 하지만 set -o pipefail
스크립트의 다른 부분이 설정되지 않을 수도 있다는 우려 때문에 단순히 를 수행하고 싶지는 않습니다 pipefail
. 물론 나중에 할 수도 있지만 내 기능 외부에 설정된 set +o pipefail
경우 pipefail
예상치 못한 동작이 발생할 수도 있습니다.
물론 가 설정된 false | true
경우 종료 코드를 측정값으로 사용할 수 있지만 pipefail
이는 약간 더러워 보입니다.
설정된 bash 옵션을 확인하는 더 일반적인(그리고 아마도 표준적인?) 방법이 있습니까?
답변1
이상 에서는 bash-4.4
다음을 사용할 수 있습니다.
myfunction() {
local -
set -o someoption
...
}
몇 가지 참고사항:
- 에서 복사한 것입니다
ash
. 에서는 옵션 세트를 저장하는 것을 로컬로ash
만드는 것이 아이디어입니다 . 에서는 변수의 값이나 속성에 영향을 주지 않기 때문에$-
작동합니다 ( 처음에 설정을 해제한 위치와는 반대로). 그래도 특수한 경우 와 동일한 방식 으로 작동합니다 . 즉, 설정이 해제되거나 기본 동작으로 되돌아 가지 않습니다.ash
ash
local
bash
bash
ash
$-
- 로 설정된 옵션만 다루고
set -o option
로 설정한 옵션은 다루지 않습니다shopt -s option
(bash
두 가지 옵션 세트가 있는 유일한 쉘입니다!). 지역 변수와 마찬가지로 정적이 아닌 동적 범위 지정입니다.
$-
함수에서 반환되면 값이 복원되지만 새 설정은 함수에서 호출하는 다른 함수나 소스 스크립트에 영향을 미칩니다. 정적 범위 지정을 원하면 ksh93으로 전환하고 다음을 사용해야 합니다.function myfunction { set -o myoption ... other_function }
Bourne 구문이 아닌 구문
other_function
으로 선언된 경우에는 영향을 받지 않습니다 .function other_function {
other_function()...
옵션을 재설정하지 않으므로 함수는 여전히 다른 코드에서 설정한 옵션의 영향을 받을 수 있습니다. 이를 방지하려면 대신 사용하고 싶을 것입니다
zsh
. 는 iszsh
와 동일 하지만 잘 알려진local -
set -o localoptions
에뮬레이션방법장소 상에서. 예를 들어:myfunction() { emulate -L zsh set -o someoption ... }
옵션을 추가하는 정상적인 zsh-default 옵션 세트(일부 예외는 있지만 문서 참조)로 시작합니다. 이는 ash/bash와 같은 동적 범위 지정이기도 하지만 다음을 사용하여 다른 함수를 호출할 수도 있습니다.
emulate zsh -c 'other_function...'
other_function
바닐라 zsh 옵션 세트로 호출됩니다 .zsh에는 또한 처음부터 전역적으로 옵션을 변경하지 않도록 할 수 있는 여러 연산자가 있습니다(예: / 에 대한
(N)
/(D)
glob 한정자 , 대소 문자를 구분 하지 않는 globbing을 위한 glob 연산자,nullglob
dotglob
(#i)
${(s:x:)var}
$IFS
${~var}
요구매개변수 확장 시 글로빙(noglob
다른 Bourne 유사 쉘에서는피하다(!) 그것)...
답변2
변수는 $SHELLOPTS
콜론으로 구분된 모든 설정 옵션을 보유합니다. 예를 들어 다음과 같습니다.
braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
특정 옵션을 확인하려면 다음을 수행하면 됩니다.
# check if pipefail is set, if not set it and remember this
if [[ ! "$SHELLOPTS" =~ "pipefail" ]]; then
set -o pipefail;
PIPEFAIL=0;
else
PIPEFAIL=1;
fi
# do something here
# reset pipefail, if it was not set before
if [ "$PIPEFAIL" -eq 0 ]; then
set +o pipefail;
fi
답변3
함수 내에서 셸 옵션을 설정하고 싶지만 호출자에게 영향을 주지 않으려면 다음 두 가지 방법을 사용하세요.
옵션 1: 서브셸
함수를 서브셸 안에 넣으세요(중괄호 대신 함수 명령문을 둘러싼 괄호에 주목하세요).
function foo() (
set -o pipefail
echo inside foo
shopt -o pipefail
# ...
)
그런 다음 호출자는 파이프 실패를 설정 해제할 수 있으며 영향을 받지 않습니다.
$ shopt -o pipefail
pipefail off
$ foo
inside foo
pipefail on
$ shopt -o pipefail
pipefail off
또는
옵션 2: 테스트 및 재설정
필요에 따라 옵션을 테스트하고 재설정할 수 있습니다(함수 명령문 주위에 중괄호가 있음 - 하위 쉘 없음).
function foo() {
shopt -q -o pipefail
local resetpipefail=$?
set -o pipefail
echo inside foo
shopt -o pipefail
# ...
# only reset pipefail if needed
[[ $resetpipefail -eq 1 ]] && set +o pipefail
}
$ shopt -o pipefail
pipefail off
$ foo
inside foo
pipefail on
$ shopt -o pipefail
pipefail off
모자 팁cuonglm그들의shopt -q
답변.
답변4
RETURN 트랩을 사용하세요
트랩 으로 지정된 명령은 셸 함수 또는 셸 스크립트를 실행 하거나 반환한
RETURN
후 실행이 다시 시작되기 전에 실행됩니다 ..
source
[...] [to shopt]
옵션-p
을 사용하면 출력이 입력으로 재사용될 수 있는 형식으로 표시됩니다.
foo() {
trap "$(shopt -p -o pipefail)" RETURN
set -o pipefail
echo inside foo
shopt -o pipefail
# ...
}
시험
$ shopt -o pipefail
pipefail off
$ foo
inside foo
pipefail on
$ shopt -o pipefail
pipefail off
다음 함수 템플릿은 함수가 반환될 때 set
및 옵션이 모두 원래 값으로 복원되도록 하는 일반적인 경우를 처리합니다.shopt
foo() {
trap "$(shopt -p -o; shopt -p)" RETURN # ①
# ...
}
① shopt -p -o
표준에 해당하는 것으로 단순화할 수 있습니다 set +o
.