Cách kiểm tra dòng lệnh bash nào đang được thực thi


15

Có cách nào để kiểm tra số dòng nào của bashtập lệnh đang được thực thi "ngay bây giờ" không?

Sử dụng có bash -x script.shvẻ hứa hẹn; tuy nhiên, tôi cần lấy số dòng hiện tại.

Câu trả lời:


20

Kết hợp xtracevới PS4bên trong tập lệnh:

$ 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

hoặc trong vỏ cha mẹ :

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

10

Vâng, đó là một cách.
Có một mảng các số dòng trong đó một hàm đã được gọi.

Xác định chức năng này:

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

Và gọi fvào bất kỳ dòng nào bạn muốn số dòng, ví dụ:

#!/bin/bash


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

f

echo next1
f

echo next2
f

echo next 3
f

Sẽ in:

6
next 1
9
next 2
12
next 3
15

Nó có thể được mở rộng để hiển thị dấu vết của các hàm được gọi là:

#!/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

Mà sẽ in:

$ ./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

Lưu ý rằng trên echo "$LINENO"đầu ra luôn luôn giống nhau (7 trong trường hợp này).


6

Bạn có thể echo $LINENOtrong một tập lệnh và nó sẽ xuất ra bất kỳ dòng nào xảy ra.

#!/bin/bash
echo $LINENO

$ ./foo.sh
2

6

Dưới đây là một giải pháp mà vay mượn phần của l0b0 củaDopeGhoti của câu trả lời (và, đến một mức độ thấp hơn, sorontar của ). Giống như những câu trả lời, tôi sử dụng $LINENOđể khám phá số dòng; Không giống như họ, tôi sử dụng trapđể kích hoạt báo cáo. trapLệnh của bash được mô tả trong bash (1) :

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

    Lệnh arg sẽ được đọc và thực thi khi shell nhận tín hiệu sigspec . ... ⁠ ︙
    ... Nếu một SIGSPECDEBUG , lệnh arg được thực hiện trước mỗi lệnh đơn giản , forlệnh, caselệnh, selectlệnh, mỗi số học forlệnh, và trước khi thực thi lệnh đầu tiên trong một chức năng vỏ ...

Vì vậy, kịch bản này:

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

chạy printf "%3d: " "$LINENO"lệnh trước mỗi lệnh trong tập lệnh và tạo đầu ra này:

$ ./myscript
  3: Thứ Tư, ngày 04 tháng 4 năm 2017 10:16:17 AM
  4: 5: Thứ Tư, ngày 04 tháng 4 năm 2017 10:16:47 AM
  7: 8: Thứ Tư, ngày 04 tháng 4 năm 2017 10:16:58 AM
 10: tổng 4
-rwxr-xr-x 1 tên người dùng mygroup 221 ngày 5 tháng 4 10:01 myscript
-rwxr-xr-x 1 tên người dùng mygroup 252 ngày 5 tháng 4 10:01 myscript2
-rw-r - r-- 1 tên người dùng mygroup 132 ngày 5 tháng 4 09:59 myscript2.log
-rw-r - r-- 1 tên người dùng mygroup   45 ngày 5 tháng 4 08:34 other_file
 11: 13: myscript
 14: -rwxr-xr-x 1 tên người dùng mygroup 221 ngày 5 tháng 4 10:01 myscript
 11: 13: myscript2
 14: -rwxr-xr-x 1 tên người dùng mygroup 252 ngày 5 tháng 4 10:01 myscript2
 11: 13: myscript2.log
 14: -rw-r - r-- 1 tên người dùng mygroup 132 ngày 5 tháng 4 09:59 myscript2.log
 11: 13: other_file
 14: -rw-r - r-- 1 tên người dùng mygroup   45 ngày 5 tháng 4 08:34 other_file
 17: 17: 19: i = 0
 19: Thứ Tư, ngày 04 tháng Tư, 2017 10:16:59 SA
 17: 17: 19: i = 1
 19: Thứ Tư, ngày 04 tháng Tư, 2017 10:16:59 SA
 17: 17: 19: i = 2
 19: Thứ Tư, ngày 04 tháng Tư, 2017 10:16:59 SA
 17: 17: 22: 42
$

Ghi chú:

  • Giống như câu trả lời của l0b0 , điều này ít xâm lấn - chỉ cần thêm dòng 2.
  • Không giống như câu trả lời của l0b0 , điều này không tự hiển thị các lệnh - nhưng bạn không yêu cầu nó thực hiện điều đó.
  • Đoạn thứ hai sleep, bao gồm các dòng script 6 và 7, được báo cáo là dòng 7.
  • Dòng 11 ( for f in *) được báo cáo một lần trước mỗi lần lặp của forvòng lặp đó .
  • echo "$f"ls -ld "$f"được báo cáo chính xác trên các dòng tương ứng của họ (13 và 14).
  • Dòng 17 ( for ((i=0; i<3; i++))) được báo cáo hai lần trước mỗi lần lặp của forvòng lặp đó và hai lần nữa sau lần lặp cuối cùng.
  • Không giống set -x, LINENOPS4 (được xác định bởi các tiêu chuẩn POSIX), các DEBUG traplà một phần mở rộng bash và sẽ không làm việc trong tất cả vỏ.
  • DEBUG trapcó thể chạy bất kỳ (các) lệnh nào và không bị hạn chế ghi vào đầu ra tiêu chuẩn hoặc lỗi tiêu chuẩn của tập lệnh.

Câu hỏi cho biết, «kiểm tra số dòng của tập lệnh bash nào đang được thực thi trực tiếp ngay bây giờ,» mà không chỉ định giao diện người dùng. Một cách tiếp cận khác là liên tục ghi số dòng hiện tại vào tệp nhật ký:

$ diff myscript myscript2
2c2
<bẫy 'printf "% 3d:" "$ LINENO"' DEBUG
---
> exec 6> myscript2.log && bẫy 'printf "% 3d \ n" "$ LINENO"> & 6' DEBUG
$ ./myscript2
Thứ tư, ngày 04 tháng 4 năm 2017 10:23:50 sáng
Thứ tư, ngày 05 tháng 4 năm 2017 10:24:20 AM
Thứ tư, ngày 05 tháng 4 năm 2017 10:24:31 AM
tổng số 4
-rwxr-xr-x 1 tên người dùng mygroup 221 ngày 5 tháng 4 10:01 myscript
-rwxr-xr-x 1 tên người dùng mygroup 252 ngày 5 tháng 4 10:01 myscript2
-rw-r - r-- 1 tên người dùng mygroup   24 tháng 4 5 10:23 myscript2.log
-rw-r - r-- 1 tên người dùng mygroup   45 ngày 5 tháng 4 08:34 other_file
bản thảo
-rwxr-xr-x 1 tên người dùng mygroup 221 ngày 5 tháng 4 10:01 myscript
myscript2
-rwxr-xr-x 1 tên người dùng mygroup 252 ngày 5 tháng 4 10:01 myscript2
myscript2.log
-rw-r - r-- 1 tên người dùng mygroup   60 ngày 5 tháng 4 10:23 myscript2.log
other_file
-rw-r - r-- 1 tên người dùng mygroup   45 ngày 5 tháng 4 08:34 other_file
i = 0
Thứ tư, ngày 05 tháng 4 năm 2017 10:24:31 AM
i = 1
Thứ tư, ngày 05 tháng 4 năm 2017 10:24:31 AM
i = 2
Thứ tư, ngày 05 tháng 4 năm 2017 10:24:31 AM
42
$

Chúng tôi có thể giám sát việc thực thi tập lệnh này bằng cách giám sát nội dung của myscript2.logtệp từ thiết bị đầu cuối khác. Ví dụ, trong lần thứ hai sleep,

$ tail myscript2.log
  3
  4
  5
  7

-1
#!/bin/bash -x

Thêm "-x" vào đầu tập lệnh của bạn. Sau đó, mỗi khi bạn thực thi tập lệnh, nó sẽ lặp lại dòng mà tập lệnh của bạn đang thực thi. giống như một cây thực thi kịch bản của bạn.


4
OP đã bác bỏ đề nghị này là không thỏa đáng.
G-Man nói 'Phục hồi Monica'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.