xtrace에 표시되지 않는 bash 함수 정의(set -x)

xtrace에 표시되지 않는 bash 함수 정의(set -x)

bash 스크립트에는 log()여러 위치에서 사용되는 함수와 logs()많은 수의 행 을 log().set -xlogs()log()

나는 정의 logs()하고 log()적어도 그 내용과 기껏해야 호출까지도 set -x출력에서 ​​억제하고 싶습니다.

답변1

함수 내에서 함수가 호출되는 방식을 변경할 수는 없지만 하위 쉘을 호출하는 함수를 정의할 수 있습니다. 그러면 일반적인 중괄호 대신 본문 주위에 괄호가 표시됩니다.

log() (
  set +x
  # rest of log()
)

그런 다음 호출은 함수의 나머지 후속 명령이 아닌 log()호출 자체(기존 set -x코드에서)와 호출만 생성합니다. 이 기능을 종료하면 기존 설정이 복원됩니다.set +xset -x

답변2

모든 쉘에서 작동해야 하는 빠르고 더러운 방법은 log함수가 아닌 외부 스크립트를 (일시적으로) 만드는 것입니다.

trap '...' DEBUGBash에서는 를 사용 하고 결합 할 수도 있는데 shopt -s extdebug, 이는 set -x.

debug() {
        local f=${FUNCNAME[1]} d=${#FUNCNAME[@]} c=$BASH_COMMAND
        if [ "$NOTRACE" ]; then
                case $debug_skip in ''|$d) debug_skip=;; *) return;; esac
                eval "case \$c in $NOTRACE) debug_skip=\$d; return; esac"
        fi

        # before the 1st command in a function XXX
        case $c in $f|"$f "*) return;; esac

        printf >&2 "%*s(%s) %s\n" $((d * 2 - 4)) "" "$f" "$c"
}

(물론 이상한 서식 + 들여쓰기를 버리고 그대로 만들 수도 있습니다 set-x. 명령에서 stderr과 혼합하는 대신 다른 파일로 리디렉션할 수도 있습니다.)

그 다음에:

NOTRACE='"log "*'
shopt -s extdebug
trap debug DEBUG

log(){ log1 "$@"; }; log1(){ log2 "$@"; }
log2(){ log3 "$@"; }; log3(){ echo "$@"; }

foo(){ foo1 "$@"; }; foo1(){ foo2 "$@"; }
foo2(){ foo3 "$@"; }; foo3(){ echo "$@"; }

bar(){ case $# in 0) ;; *) echo "$1"; shift; bar "$@";; esac; }

foo 1 2 3
log 7 8 9
bar 1 2 3 4

결과는 다음과 같습니다.

(main) foo 1 2 3
  (foo) foo1 "$@"
    (foo1) foo2 "$@"
      (foo2) foo3 "$@"
        (foo3) echo "$@"
1 2 3
7 8 9
(main) bar 1 2 3 4
  (bar) case $# in
  (bar) echo "$1"
1
  (bar) shift
    (bar) case $# in
    (bar) echo "$1"
2
    (bar) shift
      (bar) case $# in
      (bar) echo "$1"
3
      (bar) shift
        (bar) case $# in
        (bar) echo "$1"
4
        (bar) shift
          (bar) case $# in

답변3

xtrace 출력을 억제하려면 을 사용하십시오 set -x. 다시 켜려면 를 사용하십시오 set -x. 열려 있는지 확인하려면 shopt -q -o xtrace다음을 사용하세요.

log() {
  if shopt -q -o xtrace; then TRACE_IS_ON=yes; else TRACE_IS_ON=no; fi
  set +x # turn xtrace off
  ...
  [[ "$TRACE_IS_ON" == "yes" ]] && set +x
}

아직 "소소한 대화"가 좀 남아 있지만 그게 제가 할 수 있는 최선이에요. log()에 대한 호출이 표시되지 않도록 하려면 함수 내부 대신 유사한 코드로 각 log() 호출을 묶을 수 있습니다.

관련 정보