인쇄되지 않고 배쉬 세트 + x


95

set +x인쇄되지 않고 bash에서 말할 수 있는지 아는 사람이 있습니까?

set -x
command
set +x

흔적

+ command
+ set +x

그러나 그것은 단지 인쇄되어야합니다

+ command

Bash는 버전 4.1.10 (4)입니다. 이것은 지금 당분간 나를 괴롭 히고 있습니다. 출력이 쓸모없는 set +x줄로 어수선 해져서 추적 기능이 유용하지 않게 만듭니다.


이것은 귀하의 질문에 대한 답변이 아니지만 스크립트를 실행할 때 왜 안 script.sh 2>&1 | grep -v 'set +x'
됩니까?

답변:


148

나는 같은 문제가 있었고 서브 쉘을 사용하지 않는 해결책을 찾을 수있었습니다.

set -x
command
{ set +x; } 2>/dev/null

10
좋은 대답, 참고 : 명령 뒤에 세미콜론이 없으면 작동하지 않습니다. 세미콜론을 사용하지만 중괄호에 공백이 없으면 구문 오류가 발생합니다.
sdaau

9
이렇게하면 종료 상태가 0이됩니다.
Garth Kidd

8
@GarthKidd 종료 상태는 모든 성공적인 명령으로 0이됩니다. set +x이러한 성공 명령은
다니엘 알더

4
종료 상태가 필요한 command경우이 변형이 해결책 { STATUS=$?; set +x; } 2>/dev/null입니다.. 그런 다음 $STATUS여유 시간에 후속 라인을 검사 하십시오.
Greg Price

5
별도로, 여기에 약간 더 골프를 칠한 버전이 있습니다 { set +x; } 2>&-. 그것은 / dev / null을 가리 키기보다는 fd 2를 완전히 닫습니다. 일부 프로그램은 stderr로 인쇄하려고 할 때 잘 처리하지 못합니다. 이것이 / dev / null이 일반적으로 좋은 스타일 인 이유입니다. 그러나 셸의 set -x추적은 잘 처리하므로 여기서 완벽하게 작동하며이 주문을 조금 더 짧게 만듭니다.
Greg Price

43

서브 쉘을 사용할 수 있습니다. 서브 쉘을 종료하면 설정 x이 손실됩니다.

( set -x ; command )

음, 고마워요 ... 좋은 지적입니다. 사실 저는 "서브 쉘 트릭"을 알고 있습니다. 그보다 쉬울 수 있기를 바랐습니다. 이는 코드의 상당한 변경을 포함하여 코드를 더 복잡하고 읽기 어렵게 만듭니다. 세트 + x 라인으로 사는 것보다 더 나쁜 IMHO ...
Andreas Spindler

나는 ( set -x \n command \n )보다 더 나쁜 것이 보이지 않는다 set -x \n command \n set +x.
chepner

3
@chepner : 변수를 설정할 수 없습니다.
choroba

2
... 그리고 당신은 할 수 없습니다 cd: 부모 쉘의 현재 디렉토리를 변경하지 않습니다.
Andreas Spindler 2012

죄송합니다. 귀하의 실제 반대가 무엇인지 잘 모르겠습니다. 긴 한 주
였습니다

8

나는 최근에 짜증이 났을 때 이것에 대한 해결책을 해킹했습니다.

shopt -s expand_aliases
_xtrace() {
    case $1 in
        on) set -x ;;
        off) set +x ;;
    esac
}
alias xtrace='{ _xtrace $(cat); } 2>/dev/null <<<'

이를 통해 다음과 같이 xtrace를 활성화 및 비활성화 할 수 있습니다. 여기서 인수가 변수에 할당되는 방식을 로깅합니다.

xtrace on
ARG1=$1
ARG2=$2
xtrace off

그리고 다음과 같은 출력을 얻습니다.

$ ./script.sh one two
+ ARG1=one
+ ARG2=two

영리한 속임수 ( /dev/stdin부품이 필요하지는 않지만 ). 주의 할 점은 스크립트에서 별칭 확장을 설정하면 원치 않는 부작용이 발생할 수 있다는 것입니다.
mklement0

네가 옳아. 나는 불필요한을 제거하기 위해 대답을 편집했습니다 /dev/stdin. 비대화 형 환경에서는 별칭을 정의하는 파일을로드하지 않아야하므로 특정 부작용에 대해 알지 못합니다. 어떤 부작용이있을 수 있습니까?
user108471

1
그게 좋은 점입니다. 별칭이 상속되지 않았기 때문에 위험이 생각보다 훨씬 적다는 사실을 잊었습니다. 세계 관심사). +1
mklement0 2014-07-07

1
@AndreasSpindler이 기술이 더 민감한 정보를 유출 할 가능성이 더 높다고 생각하는 이유에 대해 자세히 설명해 주시겠습니까?
user108471 2015 년

1
... 기본적으로 별칭과 함수는 고수준 구조이기 때문입니다. set +x(불가능하지는 않지만) 타협하기가 훨씬 더 어렵습니다. 그러나 여전히 훌륭하고 직접적인 솔루션입니다. 아마도 지금까지 최고의 솔루션 일 것입니다.
Andreas Spindler

7

@ user108471의 단순화 된 버전을 기반으로 한 솔루션은 어떻습니까?

shopt -s expand_aliases
alias trace_on='set -x'
alias trace_off='{ set +x; } 2>/dev/null'

trace_on
...stuff...
trace_off

이건 어때? function () { set_plus_x='{ set +x; } 2>/dev/null' }
LexH

1

이것은 코드 블록을 포함하고 종료 상태를 보존 할 수있는 몇 가지 아이디어의 조합입니다.

#!/bin/bash
shopt -s expand_aliases
alias trace_on='set -x'
alias trace_off='{ PREV_STATUS=$? ; set +x; } 2>/dev/null; (exit $PREV_STATUS)'

trace_on
echo hello
trace_off
echo "status: $?"

trace_on
(exit 56)
trace_off
echo "status: $?"

실행시 :

$ ./test.sh 
+ echo hello
hello
status: 0
+ exit 56
status: 56

좋은 노력이지만 ()주위 exit는 필요하지 않다고 생각합니다 . 확인. 의 편집증하지만이 코드는 일반적으로 사용하는 경우 당신은 좋은 공격 벡터가 어쩌면 : 재정의 trace_ontrace_off및 실행 명령어를 읽어 분사 코드를. 이러한 "유틸리티"를 단독으로 사용하는 것은 유익하지만 다른 코드와 함께 사용되는 경우 이러한 비 표준화 된 기능의 이점이 단점을 능가하는지 여부를 고려해야합니다. 개인적으로 나는 { set +x; } 2>/dev/null이 구조가 일반적으로 이해되고 종료 상태를 변경하지 않기 때문에 합의했습니다 .
Andreas Spindler

감사. 나는 동료들과 접근 방식을 공유했으며 그들은 출력과 코드 모두를 덜 시끄럽게 유지하는 방법을 좋아합니다. ()주위에 관하여 exit 56; 이것은 단순히 bash 스크립트에서 하위 프로세스의 종료 상태에 액세스 할 수 있음을 보여주기위한 것입니다. 괄호가 없으면 하위 프로세스가되지 않았으며 스크립트는 해당 시점에서 status = 65로 종료되었을 것입니다.
user3286792
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.