Bash 스크립트가 실행 중인 라인을 확인하는 방법

Bash 스크립트가 실행 중인 라인을 확인하는 방법

어느 행인지 확인할 수 있는 방법이 있나요?숫자스크립트가 bash"지금" 실행되고 있습니까?

그러나 외모를 사용하면 bash -x script.sh현재 줄 번호를 얻어야 합니다.

답변1

결합하다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

답변2

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

이 함수를 정의하십시오:

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).

답변3

부품을 빌리는 솔루션이 있습니다l0b0's그리고곱고티의대답은 (그리고 어느 정도는,솔론타의). 이 답변과 마찬가지로 나는 이를 사용하여 $LINENO줄 번호를 검색하고 trap보고서를 실행하는 데 사용합니다. bash trap명령은 다음에 설명되어 있습니다.큰 타격(1):

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

    주문하다아르기닌쉘이 신호를 수신하면 읽고 실행합니다.신호 사양. … ⁠ ︙
    … 만약신호 사양디버그, 주문하다아르기닌각각 전에 실행됨간단한 명령, 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내 사용자 이름 내 그룹221년 4월 5일 10:01
-rwxr-xr-x 1내 사용자 이름 내 그룹252 4월 5일 10:01 myscript2
-rw-r--r-- 1내 사용자 이름 내 그룹132 4월 5일 09:59 myscript2.log
-rw-r--r-- 1내 사용자 이름 내 그룹  45년 4월 5일 08:34 other_file
 11:13: 내 스크립트
 14:-rwxr-xr-x 1내 사용자 이름 내 그룹221년 4월 5일 10:01
 11:13:myscript2
 14:-rwxr-xr-x 1내 사용자 이름 내 그룹252 4월 5일 10:01 myscript2
 11:13: myscript2.log
 14:-rw-r--r--1내 사용자 이름 내 그룹132 4월 5일 09:59 myscript2.log
 11:13: 기타 문서
 14:-rw-r--r--1내 사용자 이름 내 그룹  45년 4월 5일 08:34 other_file
 17:17:19:i=0
 19: 2017년 4월 5일 수요일 오전 10시 16분 59초
 17:17:19:나=1
 19: 2017년 4월 5일 수요일 오전 10시 16분 59초
 17:17:19:나=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 -xLINENO, 및 PS4 (POSIX 표준에 의해 지정됨)과 달리 DEBUG trap는 bash 확장이며 모든 쉘에서 작동하지 않습니다.
  • DEBUG는 trap모든 명령을 실행할 수 있으며 스크립트의 표준 출력이나 표준 오류에 쓰는 것으로 제한되지 않습니다.

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

$ diff myscript myscript2
2c2
< 트랩 'printf "%3d:" "$LINENO"' 디버깅 중
---
> exec 6> myscript2.log && 트랩 'printf "%3d\n" "$LINENO" >&6' 디버깅
$ ./myscript2
2017년 4월 5일 수요일 오전 10:23:50
2017년 4월 5일 수요일 오전 10:24:20
2017년 4월 5일 수요일 10:24:31
총 4개
-rwxr-xr-x 1내 사용자 이름 내 그룹221년 4월 5일 10:01
-rwxr-xr-x 1내 사용자 이름 내 그룹252 4월 5일 10:01 myscript2
-rw-r--r-- 1내 사용자 이름 내 그룹  4월 5일, 24일, 10:23 myscript2.log
-rw-r--r-- 1내 사용자 이름 내 그룹  45년 4월 5일 08:34 other_file
스크립트
-rwxr-xr-x 1내 사용자 이름 내 그룹221년 4월 5일 10:01
스크립트 2
-rwxr-xr-x 1내 사용자 이름 내 그룹252 4월 5일 10:01 myscript2
myscript2.log
-rw-r--r-- 1내 사용자 이름 내 그룹  60년 4월 5일 10:23 myscript2.log
다른 파일들
-rw-r--r-- 1내 사용자 이름 내 그룹  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다른 터미널에서 파일 내용을 모니터링하여 이 스크립트의 실행을 모니터링할 수 있습니다. 예를 들어 sleep, 두 번째 동안

$ tail myscript2.log
  3
  4
  5
  7

답변4

#!/bin/bash -x

스크립트 시작 부분에 "-x"를 추가하십시오. 그런 다음 스크립트가 실행될 때마다 스크립트가 실행 중인 줄을 에코합니다. 스크립트의 실행 트리와 같습니다.

관련 정보