如何检查bash脚本的哪一行正在执行


15

有没有一种方法来检查其行一的bash脚本执行“现在”?

使用bash -x script.sh看起来很有希望;但是,我需要获取当前行号。

Answers:


20

xtracePS4脚本内部结合:

$ 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。……… 如果sigspecDEBUG,则在每个简单命令, 命令,命令,命令,每个算术命令之前,以及在shell函数中第一个命令执行之前,都要执行命令arg ……
    forcaseselectfor

所以这个脚本:

$ 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:星期三,四月05,2017 10:16:58上午
 10:总计4
-rwxr-xr-x 1 myusername mygroup 221 Apr 5 10:01 myscript
-rwxr-xr-x 1 myusername mygroup 252 Apr 5 10:01 myscript2
-rw-r--r-- 1 myusername mygroup 132 Apr 5 09:59 myscript2.log
-rw-r--r-- 1 myusername mygroup   45 Apr 5 08:34 other_file
 11:13:myscript
 14:-rwxr-xr-x 1 myusername mygroup 221 Apr 5 10:01 myscript
 11:13:myscript2
 14:-rwxr-xr-x 1 myusername mygroup 252 Apr 5 10:01 myscript2
 11:13:myscript2.log
 14:-rw-r--r-- 1 myusername mygroup 132 Apr 5 09:59 myscript2.log
 11:13:other_file
 14:-rw-r--r-- 1 myusername mygroup   45 Apr 5 08:34 other_file
 17:17:19:i = 0
 19:2017年4月5日星期三10:16:59 AM
 17:17:19:i = 1
 19:2017年4月5日星期三10:16:59 AM
 17:17:19:i = 2
 19:2017年4月5日星期三10:16:59 AM
 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 -xLINENOPS4 (由POSIX标准指定)不同,DEBUG trap是bash扩展名,将无法在所有shell中使用。
  • DEBUG trap可以运行任何命令,并且不仅限于写入脚本的标准输出或标准错误。

该问题说:“在不指定用户界面的情况下,”立即检查正在执行的bash脚本的行号”。另一种方法是将当前行号连续写入日志文件:

$ diff myscript myscript2
2c2
<trap'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 AM
2017年4月5日星期三上午10:24:31
共4个
-rwxr-xr-x 1 myusername mygroup 221 Apr 5 10:01 myscript
-rwxr-xr-x 1 myusername mygroup 252 Apr 5 10:01 myscript2
-rw-r--r-- 1 myusername mygroup   24 Apr 5 10:23 myscript2.log
-rw-r--r-- 1 myusername mygroup   45 Apr 5 08:34 other_file
剧本
-rwxr-xr-x 1 myusername mygroup 221 Apr 5 10:01 myscript
myscript2
-rwxr-xr-x 1 myusername mygroup 252 Apr 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 Apr 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

6

您可以echo $LINENO在脚本中运行,并且应该输出该命令恰好在其上的所有行。

#!/bin/bash
echo $LINENO

$ ./foo.sh
2

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.