쉘 명령이 실행될 때 에코하는 방법


911

쉘 스크립트에서 모든 쉘 명령을 에코하고 변수 이름을 어떻게 확장합니까?

예를 들어 다음과 같은 줄이 있습니다.

ls $DIRNAME

스크립트가 명령을 실행하고 다음을 표시하고 싶습니다.

ls /full/path/to/some/dir

목적은 호출 된 모든 쉘 명령 및 해당 인수의 로그를 저장하는 것입니다. 그런 로그를 생성하는 더 좋은 방법이 있습니까?

답변:


1042

set -x또는 set -o xtrace변수를 확장하고 줄 앞에 작은 + 부호를 인쇄합니다.

set -v또는 set -o verbose인쇄하기 전에 변수를 확장하지 않습니다.

set +x및 set +v을 사용 하여 위 설정을 끄십시오.

스크립트의 첫 번째 줄에서 나중에 스크립트에서 (또는 ) 와 동일한 효과를 갖도록 #!/bin/sh -x(또는 -v) 넣을 수 있습니다 .set -x-v

위의에서도 작동합니다 /bin/sh.

set속성 및 디버깅 에 대한 bash-hackers 위키를 참조하십시오 .

$ cat shl
#!/bin/bash                                                                     

DIR=/tmp/so
ls $DIR

$ bash -x shl 
+ DIR=/tmp/so
+ ls /tmp/so
$

7
실행중인 번호가 매겨진 줄을 확인하려면 stackoverflow.com/a/17805088/1729501
— user13107

3
반향 할 때 명령과 결과 출력을 구별하기 위해 명령을 색칠하려면 어떻게해야합니까?
— Lewis Chan

10
반향 음이 들릴 때 보컬 로이드 같은 음성 합성기를 통해 각 명령을 노래하고 싶을 때 멀리서하는 일을 듣고 음악을 즐길 수 있다면 어떨까요? 아마도 입력과 출력에 대해 다른 목소리로 들릴 것입니다.
— ADJenks

(ABS는 오랜 실무 사례를 수정하라는 요청, 오랜 커뮤니티 구성원이 경쟁 리소스를 만들도록 유도하는 시점에 이르기까지 오랜 시간 동안 반응이 없었습니다. 공식 bash 매뉴얼 은 더 나은 리소스가 될 것입니다).
— Charles Duffy

316

set -x 당신이 원하는 것을 줄 것입니다.

다음은 셸 스크립트의 예입니다.

#!/bin/bash
set -x #echo on

ls $PWD

명령을 출력하기 전에 모든 변수를 확장하고 전체 명령을 인쇄합니다.

산출:

+ ls /home/user/
file1.txt file2.txt

21
그런 식으로 "verbose"라는 단어를 사용해도 아무런 효과가 없습니다. 당신은 할 수 set -o verbose또는 set -v(전용 "자세한 정보") 또는 set -o xtrace또는 set -x(전용 "xtrace") 또는 set -xv(모두) 또는 set -o xtrace -o verbose(모두).
— 추후 공지가있을 때까지 일시 중지되었습니다.

이것은 잘 작동하지만 "verbose"가 $ 1을 덮어 씁니다.
— JasonS

90

함수를 사용하여 명령을 에코하고 실행합니다.

#!/bin/bash
# Function to display commands
exe() { echo "\$ $@" ; "$@" ; }

exe echo hello world

어떤 출력

$ echo hello world
hello world

보다 복잡한 명령 파이프 등의 경우 eval을 사용할 수 있습니다.

#!/bin/bash
# Function to display commands
exe() { echo "\$ ${@/eval/}" ; "$@" ; }

exe eval "echo 'Hello, World!' | cut -d ' ' -f1"

어떤 출력

$  echo 'Hello, World!' | cut -d ' ' -f1
Hello

이 답변에 대한 투표가 많지 않습니다. 그것이 나쁜 생각 인 이유가 있습니까? 나를 위해 일하고 내가 찾고있는 것 같습니다 ...
— fru1tbat

1
모든 명령을 인쇄하지 않으려는 경우이 방법이 가장 적합합니다. ++ set +x깨끗해 보이는 것뿐만 아니라 전원을 끌 때 출력을 피합니다 . 단 하나 또는 두 개의 문장에 대해서는 서브 쉘을 사용한 bhassel의 대답이 가장 편리합니다.
— 브렌트 파우스트

이것이 내가 찾고있는 것입니다! 아니 set +x, 그것은 모든 명령에 영향을 미칩니다.
— Hlung

11
이것의 주요 단점은 출력이 인용 정보를 잃어 버린다는 것입니다. 당신은 구별 할 수 cp "foo bar" baz및 cp foo "bar baz"예를 들어,. 따라서 사용자에게 진행 정보를 표시하는 데 좋습니다. 출력 디버깅 또는 재현 가능한 명령 기록에는 적합하지 않습니다. 다른 사용 사례. 에서가 zsh, 당신은으로 인용 보존 할 수 있습니다 :q수정 :exe() { echo '$' "${@:q}" ; "$@" ; }
— 앤드류 Janke

2
이 답변이 마음에 들지 않습니다. 당신이 보는 것이 당신이 얻는 것이 아닌 많은 경우가 있습니다 (특히 공백, 따옴표, 이스케이프 된 문자, 변수 / 표현 대체 등). echoed 명령을 터미널에 맹목적으로 붙여 넣지 말고 실행한다고 가정하십시오. 같은 방식으로. 또한 두 번째 기술은 해킹 일 뿐이며 eval명령에서 다른 단어 인스턴스를 제거합니다. 따라서 제대로 작동 할 것으로 기대하지 마십시오 exe eval "echo 'eval world'"!
— mwfearnley

88

예를 들어, set -x및 에 줄 바꿈을 사용하여 스크립트에서 선택 라인에 대해 이것을 전환 할 수도 있습니다 set +x.

#!/bin/bash
...
if [[ ! -e $OUT_FILE ]];
then
   echo "grabbing $URL"
   set -x
   curl --fail --noproxy $SERV -s -S $URL -o $OUT_FILE
   set +x
fi

54

shuckc의 대답 선택 라인을 반향에 대한 몇 가지 단점을 가지고 : 다음으로 끝날 set +x명령뿐만 아니라 에코되고, 당신은 함께 종료 코드를 테스트 할 수있는 기능 잃게 $?가 덮어 도착 이후를 set +x.

또 다른 옵션은 서브 쉘에서 명령을 실행하는 것입니다.

echo "getting URL..."
( set -x ; curl -s --fail $URL -o $OUTFILE )

if [ $? -eq 0 ] ; then
    echo "curl failed"
    exit 1
fi

다음과 같은 출력을 제공합니다.

getting URL...
+ curl -s --fail http://example.com/missing -o /tmp/example
curl failed

그러나 명령에 대한 새 서브 쉘을 작성하는 오버 헤드가 발생합니다.


7
++ set +x출력 을 피하는 좋은 방법 .
— 브렌트 파우스트

3
더 나은 : 교체 if [ $? -eq 0 ]와 함께 if (set -x; COMMAND).
— Amedee Van Gasse

35

또 다른 옵션은 "-x"를 명령 줄 대신 스크립트 맨 위에 두는 것입니다.

$ cat ./server
#!/bin/bash -x
ssh user@server

$ ./server
+ ssh user@server
user@server's password: ^C
$

이 사이에 정확히 동일하게 작동하지 않습니다 ./myScript와 bash myScript. 그래도 좋은 지적입니다, 감사합니다.
— altendky

27

초보자를위한 TLDP 의 Bash Guide에 따르면 : 2 장. 스크립트 작성 및 디버깅 :

2.3.1. 전체 스크립트에서 디버깅

$ bash -x script1.sh

...

SourceForge 에서 사용할 수있는 Bash 용 본격적인 디버거가 있습니다 . 이러한 디버깅 기능은 3.x부터 최신 Bash 버전에서 사용할 수 있습니다.

2.3.2. 스크립트의 일부에 대한 디버깅

set -x            # Activate debugging from here
w
set +x            # Stop debugging from here

...

표 2-1. 세트 디버깅 옵션 개요

    Short  | Long notation | Result
    -------+---------------+--------------------------------------------------------------
    set -f | set -o noglob | Disable file name generation using metacharacters (globbing).
    set -v | set -o verbose| Prints shell input lines as they are read.
    set -x | set -o xtrace | Print command traces before executing command.

...

또는 원하는 옵션을 첫 번째 행 쉘 선언에 추가하여 스크립트 자체에서 이러한 모드를 지정할 수 있습니다. 일반적으로 UNIX 명령의 경우와 같이 옵션을 결합 할 수 있습니다.

#!/bin/bash -xv

18

Bash 스크립트 이름 앞에 명령 행에서 "bash -x"를 입력하십시오. 예를 들어, foo.sh를 실행하려면 다음을 입력하십시오.

bash -x foo.sh

11

옵션을 사용하여 디버그 모드에서 Bash 스크립트를 실행할 수 있습니다 .-x

모든 명령이 반영됩니다.

bash -x example_script.sh

# Console output
+ cd /home/user
+ mv text.txt mytext.txt

스크립트에 -x 옵션을 저장할 수도 있습니다 . -xshebang 에서 옵션을 지정하십시오 .

######## example_script.sh ###################
#!/bin/bash -x

cd /home/user
mv text.txt mytext.txt

##############################################

./example_script.sh

# Console output
+ cd /home/user
+ mv text.txt mytext.txt

2
또한 bash -vx동일하지만 변수 보간없이 할 것
— loa_in_을

4

zsh의 경우 echo

 setopt VERBOSE

디버깅을 위해

 setopt XTRACE

2

를 들어 csh와 tcsh, 당신이 할 수있는 set verbose또는set echo (또는 당신도 모두 설정할 수 있지만 일부 중복 대부분의 시간을 될 수 있습니다).

그만큼 verbose 옵션은 입력 한 것과 정확히 동일한 쉘 표현식을 인쇄합니다.

이 echo옵션은 스폰을 통해 실행될 내용을 더 많이 나타냅니다.


http://www.tcsh.org/tcsh.html/Special_shell_variables.html#verbose

http://www.tcsh.org/tcsh.html/Special_shell_variables.html#echo


Special shell variables

verbose If set, causes the words of each command to be printed, after history substitution (if any). Set by the -v command line option.

echo If set, each command with its arguments is echoed just before it is executed. For non-builtin commands all expansions occur before echoing. Builtin commands are echoed before command and filename substitution, because these substitutions are then done selectively. Set by the -x command line option.


1
$ cat exampleScript.sh
#!/bin/bash
name="karthik";
echo $name;

bash -x exampleScript.sh

출력은 다음과 같습니다.

여기에 이미지 설명을 입력하십시오


터미널의 색상 정의 (RGB, 숫자)는 무엇입니까?
— Peter Mortensen

1

복합 명령을 반향 할 수 있도록 eval플러스 Soth의 exe기능을 사용 하여 명령을 반향하고 실행합니다. 이것은 그렇지 않으면 파이프 명령의 초기 부분 만 표시하거나 표시하지 않는 파이프 명령에 유용합니다.

평가없이 :

exe() { echo "\$ $@" ; "$@" ; }
exe ls -F | grep *.txt

출력 :

$
file.txt

평가와 함께 :

exe() { echo "\$ $@" ; "$@" ; }
exe eval 'ls -F | grep *.txt'

어떤 출력

$ exe eval 'ls -F | grep *.txt'
file.txt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.