답변:
반대로하려면 a set -x
를 실행하십시오 set +x
. 대부분의 경우 문자열의 반대 set -str
는 +
: 와 같은 문자열입니다 set +str
.
일반적으로 모든 bash errexit
옵션 ( set
명령으로 변경) 을 복원 하려면 다음을 수행하십시오 (bash shopt
옵션 에 대해서는 아래를 참조하십시오 ).
oldstate="$(set +o); set -$-" # POSIXly store all set options.
.
.
set -vx; eval "$oldstate" # restore all options stored.
이 명령은
shopt -po xtrace
옵션 상태를 반영하는 실행 가능 문자열을 생성합니다. p
플래그 수단은 인쇄하고, o
우리가에 의해 옵션 (들) 설정에 대한 요구되는 플래그 지정 set
(에 의해 옵션 (들) 집합에 반대 명령 shopt
명령). 이 문자열을 변수에 할당하고 스크립트 끝에서 변수를 실행하여 초기 상태를 복원 할 수 있습니다.
# store state of xtrace option.
tracestate="$(shopt -po xtrace)"
# change xtrace as needed
echo "some commands with xtrace as externally selected"
set -x
echo "some commands with xtrace set"
# restore the value of xtrace to its original value.
eval "$tracestate"
이 솔루션은 여러 옵션에 동시에 작동합니다.
oldstate="$(shopt -po xtrace noglob errexit)"
# change options as needed
set -x
set +x
set -f
set -e
set -x
# restore to recorded state:
set +vx; eval "$oldstate"
추가 set +vx
하면 긴 옵션 목록이 인쇄되지 않습니다.
옵션 이름을 나열하지 않으면
oldstate="$(shopt -po)"
모든 옵션의 값을 제공합니다. 그리고 o
깃발 을 남기지 않으면 shopt
옵션을 사용 하여 동일한 작업을 수행 할 수 있습니다.
# store state of dotglob option.
dglobstate="$(shopt -p dotglob)"
# store state of all options.
oldstate="$(shopt -p)"
set
옵션이 설정되어 있는지 테스트해야하는 경우 가장 관용적 인 방법은 다음과 같습니다.
[[ -o xtrace ]]
다른 두 가지 유사한 테스트보다 낫습니다.
[[ $- =~ x ]]
[[ $- == *x* ]]
모든 테스트에서 다음과 같이 작동합니다.
# record the state of the xtrace option in ts (tracestate):
[ -o xtrace ] && ts='set -x' || ts='set +x'
# change xtrace as needed
echo "some commands with xtrace as externally selected"
set -x
echo "some commands with xtrace set"
# set the xtrace option back to what it was.
eval "$ts"
shopt
옵션 상태를 테스트하는 방법은 다음과 같습니다 .
if shopt -q dotglob
then
# dotglob is set, so “echo .* *” would list the dot files twice.
echo *
else
# dotglob is not set. Warning: the below will list “.” and “..”.
echo .* *
fi
모든 set
옵션 을 저장하는 간단한 POSIX 호환 솔루션 은 다음과 같습니다.
set +o
된 POSIX 표준에 기술 로서 :
+ o
현재 옵션 설정을 동일한 옵션 설정을 달성하는 명령으로 쉘에 다시 입력하기에 적합한 형식으로 표준 출력에 기록하십시오.
따라서 간단히 :
oldstate=$(set +o)
set
명령을 사용하여 설정된 모든 옵션의 값을 유지합니다 .
다시, 옵션을 원래 값으로 복원하는 것은 변수를 실행하는 문제입니다.
set +vx; eval "$oldstate"
이것은 Bash를 사용하는 것과 정확히 같습니다 shopt -po
. 이 옵션 중 일부는로 설정되어 있으므로 가능한 모든 Bash 옵션을 다루지 는 않습니다 .shopt
shopt
bash 에는 다른 쉘 옵션이 많이 있습니다 .
$ shopt
autocd off
cdable_vars off
cdspell off
checkhash off
checkjobs off
checkwinsize on
cmdhist on
compat31 off
compat32 off
compat40 off
compat41 off
compat42 off
compat43 off
complete_fullquote on
direxpand off
dirspell off
dotglob off
execfail off
expand_aliases on
extdebug off
extglob off
extquote on
failglob off
force_fignore on
globasciiranges off
globstar on
gnu_errfmt off
histappend on
histreedit off
histverify on
hostcomplete on
huponexit off
inherit_errexit off
interactive_comments on
lastpipe on
lithist off
login_shell off
mailwarn off
no_empty_cmd_completion off
nocaseglob off
nocasematch off
nullglob off
progcomp on
promptvars on
restricted_shell off
shift_verbose off
sourcepath on
xpg_echo off
그것들은 위의 변수 세트에 추가되고 같은 방식으로 복원 될 수 있습니다 :
$ oldstate="$oldstate;$(shopt -p)"
.
. # change options as needed.
.
$ eval "$oldstate"
할 수 있습니다 ( 보존 $-
을 위해 추가됩니다 errexit
).
oldstate="$(shopt -po; shopt -p); set -$-"
set +vx; eval "$oldstate" # use to restore all options.
참고 : 각 쉘은 설정되거나 설정되지 않은 옵션 목록을 작성하는 방법이 약간 다르므로 (정의 된 다른 옵션은 말할 것도없고) 문자열은 쉘간에 이식 가능하지 않지만 동일한 쉘에 유효합니다.
zsh
버전 5.3 이후 (POSIX에 따라) 올바르게 작동합니다. 이전 버전에서는 POSIX set +o
를 명령으로 쉘에 다시 입력하기에 적합한 형식으로 옵션을 인쇄했지만 설정 옵션 ( 설정되지 않은 옵션은 인쇄하지 않음) 으로 POSIX를 부분적으로 만 따랐 습니다 .
mksh (및 결과적으로 lksh)는 아직이를 수행 할 수 없습니다 (MIRBSD KSH R54 2016/11/11). mksh 매뉴얼에는 다음이 포함됩니다.
이후 버전에서 set + o는 POSIX 호환 및 인쇄 명령을 사용하여 현재 옵션을 대신 복원합니다.
bash에서 set -e
( errexit
) 값은 하위 셸 내에서 재설정되므로 set +o
$ (…) 하위 셸 내에서 값을 캡처하기가 어렵습니다 .
해결 방법으로 다음을 사용하십시오.
oldstate="$(set +o); set -$-"
Almquist 쉘과 파생물 ( dash
, NetBSD / FreeBSD sh
이상) 및 bash
4.4 이상을 사용하여 옵션을 함수에 로컬로 만들 수 있습니다 local -
( $-
원하는 경우 변수를 로컬로 설정).
$ bash-4.4 -c 'f() { local -; set -x; echo test; }; f; echo no trace'
+ echo test
test
no trace
즉 적용되지 않는 소스 파일,하지만 당신은 다시 정의 할 수 있습니다 source
로 source() { . "$@"; }
그 해결하려면.
을 사용 ksh88
하면 옵션 변경 사항이 기본적으로 함수에 로컬입니다. 함께 ksh93
정의 기능 만 사건이, function f { ...; }
구 (및 스코핑 정적 ksh88 포함한 다른 껍질에 사용되는 동적 범위 지정과 비교된다)
$ ksh93 -c 'function f { set -x; echo test; }; f; echo no trace'
+ echo test
test
no trace
에서 zsh
, 그것은 localoptions
옵션으로 완료되었습니다 :
$ zsh -c 'f() { set -o localoptions; set -x; echo test; }; f; echo no trace'
+f:0> echo test
test
no trace
POSIXly, 당신은 할 수 있습니다 :
case $- in
(*x*) restore=;;
(*) restore='set +x'; set -x
esac
echo test
{ eval "$restore";} 2> /dev/null
echo no trace
그러나 일부 쉘은 + 2> /dev/null
복원시 를 출력합니다 ( 이미 활성화 된 경우 해당 구문의 흔적 을 볼 수 있습니다). 이 접근 방식은 다시 입력 할 수 없습니다 (자신을 호출하는 함수 또는 동일한 트릭을 사용하는 다른 함수에서 수행하는 것처럼).case
set -x
이 문제를 해결하는 스택을 구현하는 방법 은 https://github.com/stephane-chazelas/misc-scripts/blob/master/locvar.sh(POSIX 셸의 변수 및 옵션에 대한 로컬 범위)를 참조 하십시오 .
어떤 쉘이든, 서브 쉘을 사용하여 옵션 범위를 제한 할 수 있습니다
$ sh -c 'f() (set -x; echo test); f; echo no trace'
+ echo test
test
no trace
그러나 이것은 옵션뿐만 아니라 모든 범위 (변수, 함수, 별칭, 리디렉션, 현재 작업 디렉토리 ...)의 범위를 제한합니다.
oldstate=$(set +o)
모든 옵션을 저장하는 더 간단한 (및 POSIX) 방법 인 것 같습니다 .
pdksh
/ mksh
(및 기타 pdksh 같은 유도체) 또는 zsh
경우 set +o
에만 기본 설정에서 편차를 출력합니다. bash / dash / yash에서는 작동하지만 이식성이 없습니다.
$-
처음에 변수를 읽고 -x
설정 여부를 확인한 다음 변수에 저장할 수 있습니다. 예 :
if [[ $- == *x* ]]; then
was_x_set=1
else
was_x_set=0
fi
로부터 배쉬 설명서 :
($-, 하이픈) 호출시, set builtin 명령 또는 쉘 자체 (예 : -i 옵션)에 의해 지정된 현재 옵션 플래그로 확장됩니다.
[[ $SHELLOPTS =~ xtrace ]] && wasset=1
set -x
echo rest of your script
[[ $wasset -eq 0 ]] && set +x
bash에서 $ SHELLOPTS 는 켜져있는 플래그로 설정됩니다. xtrace를 켜기 전에 확인하고 xtrace가 꺼져있는 경우에만 재설정하십시오.
set -x
스크립트 지속 시간 동안 적용 되는 것이 명백한 경우 , 이는 일시적인 테스트 측정 일 뿐이며 (영구적으로 출력의 일부가 아님), -x
옵션을 사용 하여 스크립트를 호출하십시오 ( 예 :
$ bash -x path_to_script.sh
... 또는 -x
옵션 을 추가하여 디버그 출력을 사용하도록 스크립트 (첫 번째 줄)를 임시로 변경하십시오 .
#!/bin/bash -x
...rest of script...
나는 이것이 아마도 당신이 원하는 것에 비해 너무 광범위하다는 것을 알고 있지만, 어쨌든 (내 경험상) 제거하고 싶을 일시적인 것들로 스크립트를 지나치게 복잡하게 만들지 않고 가장 간단하고 가장 빠르게 활성화 / 비활성화하는 방법입니다.
POSIX $-
특수 매개 변수를 통해 표시되는 플래그를 저장하고 복원하는 기능을 제공합니다 . local
지역 변수에 대한 확장을 사용합니다 . POSIX 호환 휴대용 스크립트에서는 전역 변수가 사용됩니다 ( local
키워드 없음 ).
save_opts()
{
echo $-
}
restore_opts()
{
local saved=$1
local on
local off=$-
while [ ${#saved} -gt 0 ] ; do
local rest=${saved#?}
local first=${saved%$rest}
if echo $off | grep -q $first ; then
off=$(echo $off | tr -d $first)
fi
on="$on$first"
saved=$rest
done
set ${on+"-$on"} ${off+"+$off"}
}
이것은 Linux 커널에서 인터럽트 플래그를 저장하고 복원하는 방법과 유사하게 사용됩니다.
Shell: Kernel:
flags=$(save_opts) long flags;
save_flags (flags);
set -x # or any other local_irq_disable(); /* disable irqs on this core */
# ... -x enabled ... /* ... interrupts disabled ... */
restore_opts $flags restore_flags(flags);
# ... x restored ... /* ... interrupts restored ... */
$-
변수 에서 다루지 않는 확장 옵션에는 작동하지 않습니다 .
POSIX에 내가 찾고있는 것이 있다는 것을 알았습니다. +o
인수 set
는 옵션이 아니라 eval
-ed 인 경우 옵션을 복원 하는 많은 명령을 덤프하는 명령입니다 . 그래서:
flags=$(set +o)
set -x
# ...
eval "$flags"
그게 다야.
한 가지 작은 문제는이 -x
옵션이이 옵션보다 먼저 바뀌면 eval
추악한 set -o
명령이 발생 한다는 것 입니다. 이를 제거하기 위해 다음을 수행 할 수 있습니다.
set +x # turn off trace not to see the flurry of set -o.
eval "$flags" # restore flags
서브 쉘을 사용할 수 있습니다.
(
set …
do stuff
)
Other stuff, that set does not apply to