셸 명령이 실행될 때 에코하는 방법
셸 스크립트에서 호출된 모든 셸 명령을 반향하고 변수 이름을 확장하려면 어떻게 해야 합니까?
예를 들어, 다음 행이 주어집니다.
ls $DIRNAME
스크립트에서 명령을 실행하고 다음을 표시합니다.
ls /full/path/to/some/dir
이 목적은 호출된 모든 셸 명령과 해당 인수의 로그를 저장하는 것입니다.이러한 로그를 생성하는 더 좋은 방법이 있을까요?
set -x
또는set -o xtrace
변수를 확장하고 줄 앞에 + 기호를 약간 인쇄합니다.
set -v
또는set -o verbose
에서는 인쇄하기 전에 변수를 확장하지 않습니다.
사용하다set +x
그리고.set +v
위의 설정을 해제합니다.
스크립트의 첫 줄에 다음과 같이 입력할 수 있습니다.#!/bin/sh -x
(또는)-v
)와한 효과를 set -x
(또는)-v
에 설명합니다.는 대본의 후반부에 있습니다.
위의 내용은 다음과 함께 작동합니다./bin/sh
.
속성 및 디버깅에 대한 자세한 내용은 bash-hackers의 Wiki를 참조하십시오.
$ cat shl
#!/bin/bash
DIR=/tmp/so
ls $DIR
$ bash -x shl
+ DIR=/tmp/so
+ ls /tmp/so
$
set -x
당신이 원하는 것을 줄 것입니다.
다음은 시연할 셸 스크립트의 예입니다.
#!/bin/bash
set -x #echo on
ls $PWD
이렇게 하면 모든 변수가 확장되고 명령 출력 전에 전체 명령이 인쇄됩니다.
출력:
+ ls /home/user/
file1.txt file2.txt
함수를 사용하여 다음 명령을 에코하고 실행합니다.
#!/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
스크립트에서 선택한 줄을 줄로 감싸서 이 항목을 전환할 수도 있습니다.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
선택한 라인을 반향하는 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
그러나 이 경우 명령에 대한 새 하위 셸을 생성해야 하는 오버헤드가 발생합니다.
TLDP의 Bash Guide for Bascher에 따르면: 2장. 스크립트 작성 및 디버깅:
2.3.1.
$ bash -x script1.sh
...
이제 소스포지에서 사용할 수 있는 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
다른 옵션은 명령줄 대신 스크립트 맨 위에 "-x"를 배치하는 것입니다.
$ cat ./server
#!/bin/bash -x
ssh user@server
$ ./server
+ ssh user@server
user@server's password: ^C
$
옵션을 사용하여 Bash 스크립트를 디버그 모드로 실행할 수 있습니다.
그러면 모든 명령이 반향됩니다.
bash -x example_script.sh
# Console output
+ cd /home/user
+ mv text.txt mytext.txt
스크립트에 -x 옵션을 저장할 수도 있습니다.지정하기만 하면 됩니다.-x
셰방에 있는 옵션.
######## 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
명령줄에 Bash 스크립트 이름 앞에 "bash -x"를 입력합니다.예를 들어 foo.sh 을 실행하려면 다음을 입력합니다.
bash -x foo.sh
모든 대답을 종합해보니 이것이 가장 좋고 단순한 것으로 나타났습니다.
#!/bin/bash
# https://stackoverflow.com/a/64644990/8608146
exe(){
set -x
"$@"
{ set +x; } 2>/dev/null
}
# example
exe go generate ./...
{ set +x; } 2>/dev/null
https://stackoverflow.com/a/19226038/8608146 에서
여기에 언급된 대로 명령의 종료 상태가 필요한 경우
사용하다
{ STATUS=$?; set +x; } 2>/dev/null
그리고 다음을 사용합니다.$STATUS
나중에 처럼exit $STATUS
마지막에
조금 더 유용한 것.
#!/bin/bash
# https://stackoverflow.com/a/64644990/8608146
_exe(){
[ $1 == on ] && { set -x; return; } 2>/dev/null
[ $1 == off ] && { set +x; return; } 2>/dev/null
echo + "$@"
"$@"
}
exe(){
{ _exe "$@"; } 2>/dev/null
}
# examples
exe on # turn on same as set -x
echo This command prints with +
echo This too prints with +
exe off # same as set +x
echo This does not
# can also be used for individual commands
exe echo what up!
zsh의 경우, 에코
setopt VERBOSE
디버깅을 위해서는
setopt XTRACE
복합 명령이 반향될 수 있도록 하기 위해 사용합니다.eval
플러스 소츠exe
명령을 에코하고 실행하는 기능.이 기능은 piped 명령을 실행하지 않으면 none 또는 piped 명령의 초기 부분만 표시되는 piped 명령에 유용합니다.
평가 없음:
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
위해서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.
$ cat exampleScript.sh
#!/bin/bash
name="karthik";
echo $name;
bash -x exampleScript.sh
출력은 다음과 같습니다.
소트의 대답에 따라.
강조 표시 없이 마크다운 출력을 생성할 수 있습니다(언어가 지정되지 않음).
set -x
exe() { echo "\`\$\$ ${@/eval/} \`" ; "$@" ; }
대본
set -x
exe() { echo "\`\$\$ ${@/eval/} \`" ; "$@" ; }
echo
echo -----------------------------------------------------------
echo # Setup
echo Lets take a random keyframe from in.mp4:
echo
exe eval "kfn=20"
echo
echo "kf=\$(ffprobe -v error -select_streams v -show_frames -print_format csv in.mp4 | grep 'frame,video,0,1' | head -$kfn | tail -1 | perl -pe 's|frame,video,0,1,.*?,(.*?),.*|\1|') "
exe eval "kf=$(ffprobe -v error -select_streams v -show_frames -print_format csv in.mp4 | grep 'frame,video,0,1' | head -$kfn | tail -1 | perl -pe 's|frame,video,0,1,.*?,(.*?),.*|\1|') "
echo
echo Lets select keyframe at $kf. Here are the timestamps of the all the frames from in.mp4 around this keyframe.
echo
exe eval "ffprobe -v error -select_streams v -show_frames -print_format csv in.mp4 | perl -pe 's|frame,video,0,(.*?),.*?,(.*?),.*|\2 \1|' | perl -pe 's|(.*?) 1|\1\tKF|' | perl -pe 's|(.*?) 0|\1|' |grep -A 5 -B 5 --color $kf"
echo
echo Lets compare 2 methods of split: actual losslesscut 3.53.0 and another one
echo
산출량
in.mp4에서 임의의 키 프레임을 사용합니다.
$$ kfn=20
kf=$(ffprobe -v error -select_probe v -show_frames -print_format csv in.mp4 | grep 'frame, video, 0, video, 0, 1' | head -20 | tail -1 | perl -pe's | frame, video, 0, 1, ?(.*|\1|)
$$ kf=3.803792
3.803792에서 키 프레임을 선택합니다.여기 이 키 프레임 주위의 in.mp4의 모든 프레임의 타임스탬프가 있습니다.
$$ ffprobe -v error -select_streams v -show_frames -print_format csv in.mp4 | perl -pe 's|frame,video,0,(.*?),.*?,(.*?),.*|\2 \1|' | perl -pe 's|(.*?) 1|\1\tKF|' | perl -pe 's|(.*?) 0|\1|' |grep -A 5 -B 5 --color 3.803792
3.720375
3.737083
3.753750
3.770417
3.787125
**3.803792** KF
3.820500
3.837167
3.853833
3.870542
3.887208
언급URL : https://stackoverflow.com/questions/2853803/how-to-echo-shell-commands-as-they-are-executed
'programing' 카테고리의 다른 글
몽구스에서 "LIKE" 연산자를 사용하려면 어떻게 해야 합니까? (0) | 2023.05.03 |
---|---|
스위프트에서 초기화 중에 didSet을 호출할 수 있습니까? (0) | 2023.04.28 |
모든 시트 내용을 지우는 가장 빠른 방법 VBA (0) | 2023.04.28 |
authenticationScheme이 지정되지 않았으며 기본 인증 및 사용자 지정 권한 부여로 DefaultChallengeScheme을 찾을 수 없습니다. (0) | 2023.04.28 |
Asp.net - 드롭다운 목록 맨 위에 빈 항목 추가 (0) | 2023.04.28 |