실행중인 bash 스크립트의 라인을 확인하는 방법


15

"지금"실행중인 스크립트 의 행 번호 를 확인하는 방법이 bash있습니까?

bash -x script.sh유망한 외모 사용 ; 그러나 현재 줄 번호를 가져와야합니다.

답변:


20

스크립트 내부 xtrace와 결합 PS4하십시오.

$ cat test.sh 
#!/usr/bin/env bash
set -x
PS4='+${LINENO}: '

sleep 1m
sleep 1d
$ timeout 5 ./test.sh
+3: PS4='+${LINENO}: '
+5: sleep 1m

또는 상위 쉘에서 :

$ cat test.sh 
sleep 1m
sleep 1d
$ export PS4='+${LINENO}: '
$ timeout 5 bash -x ./test.sh
+1: sleep 1m

10

예, 방법이 있습니다.
함수가 호출 된 행 번호 배열이 있습니다.

이 기능을 정의하십시오 :

f(){ echo "${BASH_LINENO[-2]}"; }

f라인 번호를 원하는 라인을 호출 하십시오 (예 :

#!/bin/bash


f(){ echo "${BASH_LINENO[-2]}"; }

f

echo next1
f

echo next2
f

echo next 3
f

인쇄합니다 :

6
next 1
9
next 2
12
next 3
15

다음과 같은 함수의 흔적을 보여주기 위해 확장 될 수 있습니다.

#!/bin/bash

f(){
    for ((i=${#BASH_LINENO[@]}-1;i>=0;i--)); do
    printf '<%s:%s> ' "${FUNCNAME[i]}" "${BASH_LINENO[i]}";
    done
    echo "$LINENO"
 }

SomeOtherFunction(){ echo -n "test the line numbering:  "; f; }

f

echo next 1
echo -n "    This line numbering:  "; f
SomeOtherFunction

echo next 2
echo -n "    This line numbering:  "; f
SomeOtherFunction

echo next 3
echo -n "    This line numbering:  "; f

다음과 같이 인쇄됩니다.

$ ./script
<main:0> <f:12> 7
next 1
    This line numbering:  <main:0> <f:15> 7
test the line numbering:  <main:0> <SomeOtherFunction:16> <f:10> 7
next 2
    This line numbering:  <main:0> <f:19> 7
test the line numbering:  <main:0> <SomeOtherFunction:20> <f:10> 7
next 3
    This line numbering:  <main:0> <f:23> 7

위의 echo "$LINENO"출력은 항상 같습니다 (이 경우 7).


7

여기에 일부 차용 솔루션의 l0b0의DopeGhoti의 답변 (조금 적게하고, sorontar의 ). 이 답변과 마찬가지로 $LINENO, 라인 번호를 찾기 위해 사용 합니다. 그들과는 달리, 나는 trap보고를 시작 하는 데 사용 합니다. bash의 trap명령은 bash (1)에 설명되어 있습니다 .

trap [-lp] [[arg] sigspec ...]

    쉘이 신호 sigspec을 수신 할 때 arg 명령 을 읽고 실행 해야 합니다. ... ⁠ ︙
    경우 ... sigspec가 있다 DEBUG 명령 인수는 모든 이전에 실행되는 간단한 명령 , for지령, case명령, select명령, 모든 연산 for명령 및 쉘 함수의 첫 번째 명령이 실행 전에 ...

따라서이 스크립트 :

$ cat -n myscript
     1  #!/bin/bash
     2  trap 'printf "%3d: " "$LINENO"' DEBUG
     3  date
     4  sleep 30
     5  date
     6  sleep \
     7        11
     8  date
     9
    10  ls -l
    11  for f in *
    12  do
    13          echo "$f"  &&
    14                         ls -ld "$f"
    15  done
    16
    17  for ((i=0; i<3; i++))
    18  do
    19          echo "i = $i"; date
    20  done
    21
    22  echo $((5+25+12))
$

printf "%3d: " "$LINENO"스크립트의 모든 명령 전에 명령을 실행하고 다음 출력을 생성합니다.

$ ./myscript
  3 : 2017 년 4 월 5 일 수요일 오전 10:16:17
  4 : 5 : 2017 년 4 월 5 일 수요일 오전 10:16:47
  7 : 8 : 수, 2017 년 4 월 5 일 10:16:58 오전
 10 : 합계 4
-rwxr-xr-x 1 myusername mygroup 221 4 월 5 일 10:01 myscript
-rwxr-xr-x 1 myusername mygroup 252 4 월 5 일 10:01 myscript2
-rw-r--r-- 1 myusername mygroup 132 4 월 5 일 09:59 myscript2.log
-rw-r--r-- 1 myusername mygroup   45 4 월 5 일 08:34 other_file
 11 : 13 : Myscript
 14 : -rwxr-xr-x 1 myusername mygroup 221 4 월 5 일 10:01 myscript
 11 : 13 : myscript2
 14 : -rwxr-xr-x 1 myusername mygroup 252 4 월 5 일 10:01 myscript2
 11 : 13 : myscript2.log
 14 : -rw-r--r-- 1 myusername mygroup 132 4 월 5 일 09:59 myscript2.log
 11 : 13 : other_file
 14 : -rw-r--r-- 1 myusername mygroup   45 4 월 5 일 08:34 other_file
 17 : 17 : 19 : i = 0
 19 : 2017 년 4 월 5 일 수요일 오전 10:16:59
 17 : 17 : 19 : i = 1
 19 : 2017 년 4 월 5 일 수요일 오전 10:16:59
 17 : 17 : 19 : i = 2
 19 : 2017 년 4 월 5 일 수요일 오전 10:16:59
 17 : 17 : 22 : 42
$

노트:

  • l0b0의 답변 과 마찬가지로 이것은 최소 침습적입니다. 2 행만 추가하면됩니다.
  • l0b0의 답변 과 달리 이것은 명령 자체를 표시하지 않지만 요청하지는 않았습니다.
  • 두 번째 sleep줄은 스크립트 줄 6과 7에 걸쳐 있으며 줄 7로보고됩니다.
  • 11 번째 줄 ( for f in *)은 해당 for루프가 반복 될 때마다 한 번보고 됩니다.
  • echo "$f"그리고 ls -ld "$f"정확하게 각각의 라인 (13, 14)에보고됩니다.
  • 17 줄 ( for ((i=0; i<3; i++)))은 루프 의 각 반복 전에 두 번, 마지막 반복 후에 두 번 더 보고 됩니다for .
  • set -x, LINENOPS4 (POSIX 표준으로 지정) 와 달리 DEBUG trap는 bash 확장이며 모든 쉘에서 작동하지는 않습니다.
  • DEBUG trap는 모든 명령을 실행할 수 있으며 스크립트의 표준 출력 또는 표준 오류에 쓰는 것으로 제한되지 않습니다.

사용자 인터페이스를 지정하지 않고 "현재 실행중인 bash 스크립트의 행 번호를 확인하십시오"라는 질문이 있습니다. 또 다른 방법은 현재 줄 번호를 지속적으로 로그 파일에 쓰는 것입니다.

$ diff myscript myscript2
2c2
<trap 'printf "% 3d :" "$ LINENO"'디버그
---
> exec 6> myscript2.log && trap 'printf "% 3d \ n" "$ LINENO"> & 6'DEBUG
$ ./myscript2
2017 년 4 월 5 일 수요일 오전 10:23:50
2017 년 4 월 5 일 수요일 오전 10:24:20
2017 년 4 월 5 일 수요일 오전 10:24:31
총 4
-rwxr-xr-x 1 myusername mygroup 221 4 월 5 일 10:01 myscript
-rwxr-xr-x 1 myusername mygroup 252 4 월 5 일 10:01 myscript2
-rw-r--r-- 1 myusername mygroup   24 4 월 5 일 10:23 myscript2.log
-rw-r--r-- 1 myusername mygroup   45 4 월 5 일 08:34 other_file
myscript
-rwxr-xr-x 1 myusername mygroup 221 4 월 5 일 10:01 myscript
myscript2
-rwxr-xr-x 1 myusername mygroup 252 4 월 5 일 10:01 myscript2
myscript2.log
-rw-r--r-- 1 myusername mygroup   60 4 월 5 일 10:23 myscript2.log
other_file
-rw-r--r-- 1 myusername mygroup   45 4 월 5 일 08:34 other_file
나는 = 0
2017 년 4 월 5 일 수요일 오전 10:24:31
나는 = 1
2017 년 4 월 5 일 수요일 오전 10:24:31
나는 = 2
2017 년 4 월 5 일 수요일 오전 10:24:31
42
$

myscript2.log다른 터미널 에서 파일 내용을 모니터링하여이 스크립트의 실행을 모니터링 할 수 있습니다 . 예를 들어, 제 2 기간 동안 sleep,

$ tail myscript2.log
  3
  4
  5
  7

6

echo $LINENO스크립트에서 수행 할 수 있으며 해당 명령이 실행되는 모든 행을 출력해야합니다.

#!/bin/bash
echo $LINENO

$ ./foo.sh
2

-1
#!/bin/bash -x

스크립트 시작 부분에 "-x"를 추가하십시오. 그런 다음 스크립트를 실행할 때마다 스크립트가 실행중인 라인을 에코합니다. 스크립트의 실행 트리처럼


4
OP는 이미이 제안이 불만족 스럽다고 기각했다.
G-Man, 'Reinstate Monica'라고
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.