기능이 있는데 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 }
other_function
function other_function {
Bourne 구문이 아닌 구문을 사용하여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)
glob 한정자 / for /(D)
, 대소문자를 구분하지 않는 와일드카드를 위한 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
모자 팁쿠엔람그들의shopt -q
답변.
답변4
RETURN 트랩 사용
트랩으로 지정된 명령은
RETURN
실행된 쉘 함수 또는 쉘 스크립트를 사용하거나 반환하기 전에 실행됩니다..
source
[...]
옵션-p
[to shopt]을 사용하면 출력이 입력으로 재사용할 수 있는 형식으로 표시됩니다.
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
.