echo 명령에 대한 실행 추적을 억제하시겠습니까?

echo 명령에 대한 실행 추적을 억제하시겠습니까?

저는 Shebang 옵션을 사용하여 쉘 스크립트를 시작하는 Jenkins의 쉘 스크립트를 실행하고 있습니다 #!/bin/sh -ex.

에 따르면인형을 위한 Bash Shebang?, -x, "쉘이 실행 추적을 인쇄하게 합니다." 이는 에코를 제외하고 대부분의 목적에 적합합니다.

echo "Message"

출력을 생성합니다

+ echo "Message"
Message

약간 중복되고 조금 이상해 보입니다. -x활성화된 상태로 두고 출력만 하는 방법이 있습니까?

Message

위의 두 줄 대신에, 예를 들어 echo 명령 앞에 특수 명령 문자를 붙이거나 출력을 리디렉션하는 방법을 사용하시겠습니까?

답변1

악어에 목까지 차면 목표가 늪의 배수라는 사실을 잊기 쉽습니다.                    — 대중적인 말

질문은echo, 그러나 지금까지의 답변의 대부분은 set +x명령을 몰래 입력하는 방법에 중점을 두었습니다. 훨씬 더 간단하고 직접적인 솔루션이 있습니다.

{ echo "Message"; } 2> /dev/null

{ …; } 2> /dev/null ( 이전 답변에서 보지 못했다면 생각하지 못했을 수도 있음을 인정합니다 .)

이는 다소 번거롭지만 연속된 명령 블록이 있는 경우 echo각 명령에 대해 개별적으로 수행할 필요는 없습니다.

{
  echo "The quick brown fox"
  echo "jumps over the lazy dog."
} 2> /dev/null

개행 문자가 있는 경우에는 세미콜론이 필요하지 않습니다.

를 사용하면 타이핑 부담을 줄일 수 있습니다.케노브의 생각/dev/null비표준 파일 설명자(예: 3)를 영구적으로 열고 항상 2>&3대신 이렇게 말하는 것입니다.2> /dev/null


이 글을 쓰는 시점에서 처음 네 가지 답변은 특별한 작업을 요구합니다(그리고 대부분의 경우 번거롭습니다). 모든당신이 할 시간은 echo. 정말로 원한다면모두 echo실행 추적을 억제하는 명령(그렇지 않은 이유는 무엇입니까?)을 사용하면 많은 코드를 삭제하지 않고도 전역적으로 그렇게 할 수 있습니다. 먼저 별칭이 추적되지 않는 것을 확인했습니다.

$ myfunc()
> {
>     date
> }
$ alias myalias="date"
$ set -x
$ date
+ date
Mon, Oct 31, 2016  0:00:00 AM           # Happy Halloween!
$ myfunc
+ myfunc                                # Note that function call is traced.
+ date
Mon, Oct 31, 2016  0:00:01 AM
$ myalias
+ date                                  # Note that it doesn’t say  + myalias
Mon, Oct 31, 2016  0:00:02 AM

(다음 스크립트 스니펫은 shebang이 bash에 대한 링크 #!/bin/sh인 경우에도 작동합니다 /bin/sh. 그러나 shebang이 이면 스크립트에서 별칭이 작동하도록 하려면 명령을 #!/bin/bash추가해야 합니다 .)shopt -s expand_aliases

그래서 첫 번째 트릭은 다음과 같습니다.

alias echo='{ set +x; } 2> /dev/null; builtin echo'

이제 이라고 말하면 echo "Message"추적되지 않는 별칭을 호출하는 것입니다. 별칭은 추적 옵션을 끄는 동시에 명령에서 추적 메시지를 억제합니다 set(처음에 제시된 기술 사용).user5071535의 답변), 실제 echo명령을 실행합니다. 이를 통해 코드를 편집할 필요 없이 user5071535의 답변과 유사한 효과를 얻을 수 있습니다.모든 echo명령. 그러나 이렇게 하면 추적 모드가 꺼진 상태로 유지됩니다. set -x별칭은 단어를 문자열로 대체할 수만 있기 때문에 별칭에 a를 넣을 수 없습니다 (또는 적어도 쉽지는 않습니다). 별칭 문자열의 어떤 부분도 명령에 삽입할 수 없습니다. ~ 후에인수(예: "Message"). 예를 들어 스크립트에 다음이 포함되어 있는 경우

date
echo "The quick brown fox"
echo "jumps over the lazy dog."
date

출력은

+ date
Mon, Oct 31, 2016  0:00:03 AM
The quick brown fox
jumps over the lazy dog.
Mon, Oct 31, 2016  0:00:04 AM           # Note that it doesn’t say  + date

따라서 메시지를 표시한 후에도 추적 옵션을 다시 켜야 합니다. 하지만 매회 한 번만 가능합니다.차단하다연속 echo명령 중:

date
echo "The quick brown fox"
echo "jumps over the lazy dog."
set -x
date


그것은 좋은 것입니다set -x만약 우리가 a 이후에 자동 을 만들 수 있다면 echo– 그리고 우리는 좀 더 속임수를 써서 할 수 있습니다. 하지만 그것을 발표하기 전에 이것을 고려해 보세요. OP는 #!/bin/sh -exshebang을 사용하는 스크립트로 시작됩니다. 암시적으로 사용자는 xshebang에서를 제거하고 실행 추적 없이 정상적으로 작동하는 스크립트를 가질 수 있습니다. 해당 속성을 유지하는 솔루션을 개발할 수 있다면 좋을 것입니다. 여기에서 처음 몇 가지 답변은 echo이미 켜져 있는지 여부에 관계없이 무조건 after 문에 대한 추적을 "다시" 설정하기 때문에 해당 속성에 실패합니다.  이 답변그 문제를 눈에 띄게 인식하지 못하기 때문에대체하다 echo추적 출력으로 출력; 따라서 추적이 꺼지면 모든 메시지가 사라집니다. 이제 echo명령문 이후에 추적을 다시 시작하는 솔루션을 제시하겠습니다.조건부로— 이미 켜져 있는 경우에만 해당됩니다. 이것을 무조건 "역추적"으로 전환하는 솔루션으로 다운그레이드하는 것은 사소한 일이며 연습으로 남겨둡니다.

alias echo='{ save_flags="$-"; set +x;} 2> /dev/null; echo_and_restore'
echo_and_restore() {
        builtin echo "$*"
        case "$save_flags" in
         (*x*)  set -x
        esac
}

$-옵션 목록입니다. 설정된 모든 옵션에 해당하는 문자의 연결입니다. 예를 들어 ex옵션이 설정된 경우 및가 $-포함된 문자가 뒤섞여 표시됩니다 . 내 새 별칭(위)은 추적을 끄기 전의 값을 저장합니다 . 그런 다음 추적을 끄면 쉘 기능에 제어권이 넘겨집니다. 해당 함수는 실제 작업을 수행 한 다음 별칭이 호출될 때 옵션이 켜져 있는지 확인합니다 . 옵션이 켜져 있으면 함수가 다시 켜집니다. 꺼져 있으면 함수가 꺼진 상태로 유지됩니다.ex$-echox

위의 7줄(을 포함하는 경우 8줄 shopt)을 스크립트 시작 부분에 삽입하고 나머지는 그대로 놔둘 수 있습니다.

이것은 당신을 허용할 것입니다

  1. 다음 shebang 라인 중 하나를 사용하려면:
    #!/bin/sh -ex
    #!/bin/sh -e
    #!/bin/sh –x
    아니면 그냥 평범하다
    #!/bin/sh
    예상대로 작동해야 합니다.
  2. 다음과 같은 코드를 갖도록
    (오두막)
    명령 1
    명령 2
    명령 3
    세트 -x
    명령 4
    명령 5
    명령 6
    +x로 설정
    명령 7
    명령 8
    명령 9
    그리고
    • 명령 4, 5, 6이 추적됩니다. 그 중 하나가 가 아닌 echo경우에는 실행되지만 추적되지는 않습니다. (그러나 명령 5가 라도 echo명령 6은 계속 추적됩니다.)
    • 명령 7, 8, 9는 추적되지 않습니다. 명령 8이 라도 echo명령 9는 여전히 추적되지 않습니다.
    • 명령 1, 2, 3은 shebang에 포함되어 있는지 여부에 따라 추적되거나(예: 4, 5, 6) 추적되지 않습니다(예: 7, 8, 9) x.

builtin추신: 내 시스템에서 중간 답변(의 별칭인 키워드 ) 을 생략할 수 있다는 것을 발견했습니다 echo. 이는 놀라운 일이 아닙니다. bash(1)은 별칭 확장 중에 다음과 같이 말합니다.

... 확장되는 별칭과 동일한 단어는 두 번째로 확장되지 않습니다. 이는 별칭을 지정할 수 있음을 의미합니다.ls에게ls -F예를 들어 bash는 대체 텍스트를 재귀적으로 확장하려고 시도하지 않습니다.

놀랍지도 않게 도 키워드가 생략 되면 마지막 답변( 가 포함된 답변 echo_and_restore)이 실패합니다 1 . 그러나 이상하게도 을 삭제 하고 순서를 바꾸면 작동합니다.builtinbuiltin

echo_and_restore() {
        echo "$*"
        case "$save_flags" in
         (*x*)  set -x
        esac
}
alias echo='{ save_flags="$-"; set +x;} 2> /dev/null; echo_and_restore'

__________
1  정의되지 않은 동작이 발생하는 것 같습니다. 나는 본 적이

  • 무한 루프(아마도 무한 재귀 때문일 것임),
  • 오류 /dev/null: Bad address메시지 및
  • 코어 덤프.

답변2

부분적인 해결책을 찾았습니다.InformIT:

#!/bin/bash -ex
set +x; 
echo "shell tracing is disabled here"; set -x;
echo "but is enabled here"

출력

set +x; 
shell tracing is disabled here 
+ echo "but is enabled here"
but is enabled here

불행하게도 그 소리는 여전히 울려 퍼지지 set +x만 적어도 그 이후에는 조용합니다. 따라서 이는 문제에 대한 적어도 부분적인 해결책입니다.

하지만 이 작업을 수행하는 더 좋은 방법이 있을까요? :)

답변3

이 방법은 출력을 제거하여 자신의 솔루션을 개선합니다 set +x.

#!/bin/bash -ex
{ set +x; } 2>/dev/null
echo "shell tracing is disabled here"; set -x;
echo "but is enabled here"

답변4

set +x괄호 안에 넣으면 로컬 범위에만 적용됩니다.

예를 들어:

#!/bin/bash -x
exec 3<> /dev/null
(echo foo1 $(set +x)) 2>&3
($(set +x) echo foo2) 2>&3
( set +x; echo foo3 ) 2>&3
true

다음과 같이 출력됩니다.

$ ./foo.sh 
+ exec
foo1
foo2
foo3
+ true

관련 정보