디버깅을 위해 현재 실행중인 bash 스크립트가 -x로 호출되었는지 어떻게 알 수 있습니까?


11

launch.sh올바른 소유자가있는 파일을 만들 수 있도록 다른 사용자로 실행 되는 스크립트 가 있습니다. 원래 스크립트에 전달 된 경우이 호출에 -x를 전달하고 싶습니다.

if [ `whoami` == "deployuser" ]; then
  ... bunch of commands that need files to be created as deployuser
else
  echo "Respawning myself as the deployment user... #Inception"
  echo "Called with: <$BASH_ARGV>, <$BASH_EXECUTION_STRING>, <$->"
  sudo -u deployuser -H bash $0 "$@"  # How to pass -x here if it was passed to the script initially?
fi

bash 디버깅 페이지를 읽었 지만 원래 스크립트가 시작되었는지 여부를 알려주는 명확한 옵션이없는 것 같습니다 -x.

답변:


15

bash명령 행에 전달 될 수있는 많은 플래그 는 set플래그입니다. set런타임에 이러한 플래그를 토글 할 수있는 쉘 내장 기능입니다. 예를 들어, 스크립트를 호출하는 bash -x foo.sh것은 기본적으로 set -x스크립트 맨 위에서 수행하는 것과 동일 합니다.

set이것이 책임이있는 쉘 내장 임을 알면 어디를 볼 수 있는지 알 수 있습니다. 이제 할 수 help set있고 다음을 얻습니다.

$ help set
set: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...]
...
      -x  Print commands and their arguments as they are executed.
...
    Using + rather than - causes these flags to be turned off.  The
    flags can also be used upon invocation of the shell.  The current
    set of flags may be found in $-.  The remaining n ARGs are positional
    parameters and are assigned, in order, to $1, $2, .. $n.  If no
    ARGs are given, all shell variables are printed.
...

이로부터 $-우리는 어떤 플래그가 활성화되어 있는지 알려 주어야합니다.

$ bash -c 'echo $-'
hBc

$ bash -x -c 'echo $-'
+ echo hxBc
hxBc

따라서 기본적으로 다음을 수행하면됩니다.

if [[ "$-" = *"x"* ]]; then
  echo '`-x` is set'
else
  echo '`-x` is not set'
fi

보너스로 모든 플래그를 복사하려면 다음을 수행하십시오.

bash -$- /other/script.sh

1
[[ $- == *x* ]]패턴 일치 에 사용해야 합니다.
glenn jackman 1

1
또는 표준을 사용할 수 있습니다 case $- in *x*) ... ;; *) ... ;; esac. 그것은이 사용 알고 유용 case이식을 의미하는 스크립트를, 지금은 그것을 알고, 나는 "만약 bash는 고유하고 기억하는 것보다 더 쉽게 그냥 그 기억을 찾아 [[, 다른 case".
hvd

그렇다면이 일련의 주석을 모두 삭제할 수 있습니다.
l0b0

$-출력 hB. 뭐라고합니까 -h-B플래그 / 인자합니까? bash man page 에서 보지 마십시오 .
Dan Dascalescu

3

set -o를 사용하면 출력 되고 그렇지 않으면 출력 xtrace on됩니다 .-xxtrace off


2

@Patrick의 답변이 "올바른"답변이지만 추적 기능 켜기와 같이 수행 할 작업을 알려주는 매개 변수 또는 내 보낸 변수를 자식 스크립트에 전달할 수도 있습니다.

이것은 입력하려는 각 스크립트 레벨로 다시 내 보내야한다는 단점이 있습니다.

외부 출력 등을 줄이기 위해 출력 / 수정 된 동작을 필요로하는 스크립트 만 선택적으로 추적 (또는 다른 방식으로 영향) 할 수 있다는 장점이 있습니다. 호출 된 스크립트에서 여전히 켜져 있습니다. 전부가 아니거나 제안이 아닙니다.

귀하의 질문의 일부는 아니지만 관련 :

때로는 다음과 같은 변수를 정의합니다

E=""
E="echo "

또는

E=""
E=": "

다음과 같이 여러 문장으로 사용하십시오.

"${E}" rsync ...

또는 두 번째 변형의 경우

"${E}" echo "this is a debugging message"

그런 다음 명령을 실행하려고 할 때 두 번째 정의를 주석 처리합니다. 대신이 기술을 매개 변수 또는 내 보낸 변수와 함께 사용할 수도 있습니다.

이 중 하나를 사용하면 복합 목록의 첫 번째 명령문에서만 작동하기 때문에 복합 명령문에주의해야합니다.


1

프로세스의 PID를 잡고 ps로 프로세스 테이블을 검사하여 인수가 무엇인지 확인할 수 있습니다.


다음을 통해 프로세스 PID를 가져올 수 있습니다. $$
Paul Calabro

2
-x스크립트 안에 설정하면 ps출력 으로 표시되지 않기 때문에 일반적으로 좋은 생각 은 아닙니다 . 그리고이 솔루션은 어쨌든 비효율적입니다.
vinc17

그것은 공정한 논쟁입니다. 나는 실제로 $-변수에 대해 몰랐다. 이 문제를 해결하는 데 훨씬 더 나은 방법으로 보입니다.
Paul Calabro

1
set -o내가 제안한 솔루션 도 있습니다 . 또한 이와 같은 플래그가없는 옵션에 대해서도 작동합니다 -x.
vinc17
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.