![](/img/trans.png)
[英]save output and execution time of command in diffrent variables in bash script
[英]How to debug a bash script and get execution time per command
我有一個bash
腳本,需要將近5秒鍾才能運行。 我想調試它,並確定哪些命令花費的時間最長。 這樣做的最佳方式是什么? 我可以設置一個標志嗎? 設置#!/bin/bash -vx
並沒有什么幫助。 我想要的基本上是按行號執行時間。
這是盡可能接近內置bash調試工具的答案,因為它提供了腳本執行開始時間的整體時序信息。
在腳本的頂部添加此項以進行第二次計數:
export PS4='+[${SECONDS}s][${BASH_SOURCE}:${LINENO}]: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'; set -x;
相同但是用毫秒代替:
N=`date +%s%N`; export PS4='+[$(((`date +%s%N`-$N)/1000000))ms][${BASH_SOURCE}:${LINENO}]: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'; set -x;
最后一個例子可以達到微秒精度,請記住你正在使用bash :)。
示例腳本:
#!/bin/bash
N=`date +%s%N`
export PS4='+[$(((`date +%s%N`-$N)/1000000))ms][${BASH_SOURCE}:${LINENO}]: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'; set -x;
sleep 1
exit
調試輸出示例:
+[3ms][/root/db_test.sh:5]: sleep 1
+[1012ms][/usr/local/bin/graphite_as_rand_stat.sh:6]: exit
請記住,您可以選擇性地調試腳本的特定部分,方法是將其封裝在調試開始時的“set -x”和調試結束時的“debug + x”中。 從執行開始,定時數據仍將正確顯示。
附錄
為了完整起見,如果確實需要差分計時數據,可以將調試信息重定向到文件並在之后處理。
鑒於此示例腳本:
#!/bin/bash
N=`date +%s%N`
export PS4='+[$(((`date +%s%N`-$N)/1000000))ms][${BASH_SOURCE}:${LINENO}]: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'; set -x;
sleep 1
for ((i=0;i<2;i++)); do
o=$(($RANDOM*$RANDOM/$RANDOM))
echo $o
sleep 0.$o
done
exit
在將調試重定向到文件時運行它:
./example.sh 2>example.dbg
並輸出差分調試時序(涵蓋多線):
p=0; cat example.dbg | while read l; do [[ ! ${l%%[*} =~ ^\+ ]] && echo $l && continue; i=`echo $l | sed 's#[^0-9]*\([0-9]\+\).*#\1#'`; echo $l | sed "s#${i}ms#${i}ms+$(($i-$p))ms#"; p=$i; done
輸出:
+[2ms+2ms][./example.sh:5]: sleep 1
+[1006ms+1004ms][./example.sh:6]: (( i=0 ))
+[1009ms+3ms][./example.sh:6]: (( i<2 ))
+[1011ms+2ms][./example.sh:7]: o=19258
+[1014ms+3ms][./example.sh:8]: echo 19258
+[1016ms+2ms][./example.sh:9]: sleep 0.19258
+[1213ms+197ms][./example.sh:6]: (( i++ ))
+[1217ms+4ms][./example.sh:6]: (( i<2 ))
+[1220ms+3ms][./example.sh:7]: o=176
+[1226ms+6ms][./example.sh:8]: echo 176
+[1229ms+3ms][./example.sh:9]: sleep 0.176
+[1442ms+213ms][./example.sh:6]: (( i++ ))
+[1460ms+18ms][./example.sh:6]: (( i<2 ))
+[1502ms+42ms][./example.sh:11]: exit
您可以使用time
實用程序來測量各個命令/功能的運行時間。
例如:
[ben@imac ~]$ cat times.sh
#!/bin/bash
test_func ()
{
sleep 1
echo "test"
}
echo "Running test_func()"
time test_func
echo "Running a 5 second external command"
time sleep 5
運行該腳本會產生以下內容:
[ben@imac ~]$ ./times.sh
Running test_func()
test
real 0m1.003s
user 0m0.001s
sys 0m0.001s
Running a 5 second external command
real 0m5.002s
user 0m0.001s
sys 0m0.001s
您可以使用set -x
讓腳本在執行之前打印每個命令。 我不知道如何自動添加命令時序。 您可以在整個腳本中使用date
命令來標記時間。
嘗試這個:
sed 's/^\([^#]\)/time \1/' script.sh>tmp.sh && ./tmp.sh
它為所有非命令行添加時間命令
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.