set -x
무작정 설정하는 것보다 스크립트 시작 부분에서 "실행 취소"(설정 전 상태로 돌아가기) 하고 싶습니다 +x
. 이것이 가능합니까?
추신 : 확인했습니다여기;내가 아는 한 이것은 내 질문에 대한 대답이 아닌 것 같습니다.
답변1
추상적인
을 되돌리려 set -x
면 set +x
. 대부분의 경우 문자열의 반대는 : 과 동일한 문자열 set -str
입니다 .+
set +str
일반적으로 모든 errexit
셸 옵션(bash에 대해 아래 참조)을 복원하려면(명령을 사용하여 변경됨 set
) 다음을 수행할 수 있습니다(bash shopt
옵션에 대해서도 아래 참조).
oldstate="$(set +o)" # POSIXly store all set options.
.
.
set -vx; eval "$oldstate" # restore all options stored.
충분해야 하지만 bash에는 set
(or ) 및 일부를 통해 shopt -po
액세스되는 두 가지 옵션 세트가 있습니다. 또한 bash는 shopt -p
하위 쉘에 들어갈 때 지속 set -e
(errexit) 되지 않습니다. 확장으로 생성된 옵션 목록은 $-
셸에 다시 입력되지 않을 수 있습니다.
bash에서 전체 현재 상태를 캡처하려면 다음을 사용하십시오.
oldstate="$(shopt -po; shopt -p)"; [[ -o errexit ]] && oldstate="$oldstate; set -e"
inherit_errexit
또는 플래그 설정이 마음에 들지 않는 경우 (그리고 bash는 ≥4.4입니다):
shopt -s inherit_errexit; oldstate="$(shopt -po; shopt -p)"
더 긴 설명
세게 때리다
이 명령은 다음과 같습니다.
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
가장 관용적인(Bash) 방법은 다음과 같습니다.
[[ -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
POSIX
모든 옵션을 저장하기 위한 간단한 POSIX 호환 솔루션은 set
다음과 같습니다.
set +o
이것은POSIX 표준에 설명되어 있음처럼:
+o
동일한 옵션 설정을 구현하는 명령으로 셸에 다시 입력하기에 적합한 형식으로 현재 옵션 설정을 표준 출력에 기록합니다.
간단히 말해서 다음과 같습니다.
oldstate=$(set +o)
set
이 명령으로 설정된 모든 옵션의 값은 (일부 쉘에서는) 유지됩니다 .
마찬가지로 옵션을 원래 값으로 복원하는 것은 단순히 변수를 실행하는 문제입니다.
set +vx; eval "$oldstate"
이는 Bash를 사용하는 것과 동일합니다 shopt -po
.아니요씌우다모두가능한불다옵션 중 일부만 제공되기 때문입니다 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"
배쉬의 set -e
특별한 경우
set -e
Bash에서는 ( )의 값이 errexit
서브셸 내에서 재설정되므로 set +o
$(...) 서브셸 내에서 해당 값을 캡처하기가 어렵습니다.
해결 방법으로 다음을 사용하십시오.
oldstate="$(set +o)"; [[ -o errexit ]] && oldstate="$oldstate; set -e"
또는 (목표와 충돌하지 않고 bash가 이를 지원하는 경우) 이 inherit_errexit
옵션을 사용할 수 있습니다.
노트: 각 셸은 설정 또는 설정 해제 옵션 목록을 약간 다르게 작성하므로(다른 옵션이 정의된 것은 말할 것도 없고) 문자열은 셸 간에 이식 가능하지 않지만 동일한 셸에서는 유효합니다.
zsh 특별한 경우
zsh
또한 버전 5.3(POSIX 호환)부터 잘 작동합니다. 이전 버전에서는 set +o
셸에 명령으로 다시 입력하는 데 적합한 형식으로 옵션을 인쇄한다는 점에서 POSIX를 부분적으로 따랐습니다.놓다옵션(인쇄되지 않습니다.설정되지 않음옵션).
mksh 특별한 경우
mksh(및 결과 lksh)는 아직 이 작업을 수행할 수 없습니다(MIRBSD KSH R54 2016/11/11). mksh 매뉴얼에는 다음 내용이 포함되어 있습니다.
향후 릴리스에서는 set +o가 POSIX 규격으로 작동하고 현재 옵션을 복원하는 명령을 인쇄합니다.
답변2
Almquist 셸 및 파생물(적어도 dash
NetBSD/FreeBSD) 및 4.4 이상을 사용하면 다음을 사용하여 옵션을 함수에 대한 로컬(원하는 경우 로컬 변수에 대한 변수)로 설정할 수 있습니다.sh
bash
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
그러나 이는 옵션뿐만 아니라 모든 것(변수, 함수, 별칭, 리디렉션, 현재 작업 디렉터리...)의 범위를 제한합니다.
답변3
$-
처음에 변수를 읽어 -x
설정되어 있는지 확인한 다음 변수에 저장할 수 있습니다 .
if [[ $- == *x* ]]; then
was_x_set=1
else
was_x_set=0
fi
~에서배쉬 매뉴얼:
($-, 하이픈.) 호출 시 지정된 현재 옵션 플래그, 내장 설정에 의해 설정되거나 쉘 자체에 의해 설정(예: -i 옵션)으로 확장됩니다.
답변4
확실히 하기 위해, set -x
이것이 스크립트 기간 동안 유효하고 임시 테스트 측정일 뿐이라면(출력의 영구적인 부분이 아님) 옵션을 사용하여 스크립트를 호출하십시오 -x
.
$ bash -x path_to_script.sh
...또는 옵션을 추가하여 디버그 출력을 활성화하도록 스크립트(첫 번째 줄)를 일시적으로 변경합니다 -x
.
#!/bin/bash -x
...rest of script...
나는 이것이 당신이 원하는 것에 비해 너무 광범위하다는 것을 알고 있지만 (내 경험에 따르면) 제거하고 싶은 임시 항목으로 스크립트를 지나치게 복잡하게 만들지 않고 활성화/비활성화하는 가장 쉽고 빠른 방법입니다.