Answers:
是的,有办法。
有一个已调用函数的行号数组。
定义此功能:
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)。
下面是借用的份溶液l0b0的和DopeGhoti的答案(以及在较小程度上,sorontar的)。像那些答案一样,我$LINENO
用来发现行号。不像他们,我trap
用来触发报告。bash的trap
命令在bash(1)中进行了描述:
trap [-lp] [[arg] sigspec ...]
当外壳接收到信号sigspec时,将读取并执行 命令arg。……… 如果sigspec为DEBUG,则在每个简单命令, 命令,命令,命令,每个算术命令之前,以及在shell函数中第一个命令执行之前,都要执行命令arg ……
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:星期三,四月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 $
笔记:
sleep
跨脚本第6行和第7行,报告为第7行。for f in *
)在该for
循环的每次迭代之前报告一次。echo "$f"
并ls -ld "$f"
在各自的行(13和14)上正确报告。for ((i=0; i<3; i++))
)
在该循环的每次迭代之前报告两次for
,在最后一次迭代之后报告两次。set -x
,LINENO
和PS4
(由POSIX标准指定)不同,DEBUG trap
是bash扩展名,将无法在所有shell中使用。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
#!/bin/bash -x
在脚本的开头添加“ -x”。然后,每次执行脚本时,它将回显脚本正在执行的行。就像脚本的执行树。