[英]Keep track of execution time in a bash script and terminate current command if it takes too long
[英]Bash Script execution too long
我在制作一個腳本時遇到了麻煩,時間執行太長(例如24分鍾),但是時間是可變的(取決於日志的時間),並且在不久的將來,時間肯定會增加。
troube處於嵌套的for循環中:
obtener_ErroresLanzados()
{
#Buscamos los equipos del log lanzados_a_pendientes en los logs de instala_sw_qcc para ver el porque no se han lanzado.
totalLanzadosPendientes=`cat $rutaTemporales/lanzados_a_pendientes.log | wc -l`;
lanzadosPendientes=$(cat $rutaTemporales/lanzados_a_pendientes.log);
#grep "$paqueteBuscado" instala_sw_qcc_2012*.log | cut -f 1 -d ":" > $rutaTemporales/logsErrores.log;
find $rutaTrazas -name "instala_sw_qcc_2012*" | xargs grep -l "$rutaQcc/$paqueteBuscado" | xargs grep -l "ERROR \[" | cut -f 9 -d "/" > $rutaTemporales/logsErrores.log;
logsErrores=$(cat $rutaTemporales/logsErrores.log);
totalLogsErrores=`cat $rutaTemporales/logsErrores.log | wc -l`;
for (( j=1; j<=$totalLanzadosPendientes; j++ ))
do
equipoBusqueda=`echo $lanzadosPendientes | cut -f $j -d " "`;
for (( k=1; k<=$totalLogsErrores; k++ ))
do
logBusqueda=`echo $logsErrores | cut -f $k -d " "`;
grep "ERROR \[$equipoBusqueda\]" $rutaTrazas/$logBusqueda >> $rutaTemporales/erroresPendientes.log;
if [ $? -eq 0 ];then
break;
fi;
done;
done;
cat $rutaTemporales/erroresPendientes.log | sed 's/ / /g' | sed '/No se ha podido/d' | cut -f 7-14 -d " " | sort -u > $rutaTemporales/erroresPendientes_Final.log;
}
問題在於$ totalLogsErrores大於20k ...
我可以用其他方式做到嗎?
謝謝!
-----------------------編輯1 -----------------------
$ time find $rutaTrazas -name "instala_sw_qcc_2012*" | xargs grep -l "$rutaQcc/$paqueteBuscado" | xargs grep -l "ERROR [" | cut -f 9 -d "/"
real 0m3.862s
user 0m0.959s
sys 0m2.941s
$ du -h ../trazas/instala_sw_qcc_20120718091838.log
4.0K ../trazas/instala_sw_qcc_20120718091838.log
$ time grep error ../trazas/instala_sw_qcc_20120718091838.log
real 0m0.001s
user 0m0.001s
sys 0m0.000s
要解決此性能問題,可以嘗試以下操作:
評估第一個find
& grep
命令的影響:
$ time find $rutaTrazas -name "instala_sw_qcc_2012*" | xargs grep -l "$rutaQcc/$paqueteBuscado" | xargs grep -l "ERROR \[" | cut -f 9 -d "/" > $rutaTemporales/logsErrores.log;
在你的嵌套for
循環,評估影響grep
。 文件有多大? 在您的評論中,您提到了100*10000
重復,如果每個grep
花費4毫秒,這將是巨大的。
當您有很多子目錄時, find
將變得昂貴,而當文件足夠大時, grep
將變得昂貴。
$ du -h file.out
20K file.out
$ time grep ERROR file.out
real 0m0.004s
user 0m0.000s
sys 0m0.003s
如果您有1000000循環,那將花費很多:)
cat的無用用法: wc -l <file
代替cat file | wc -l
cat file | wc -l
wc的無用用法: while read line; do ...;done <file
while read line; do ...;done <file
而不是for循環:
find $rutaTrazas -name "instala_sw_qcc_2012*" | xargs grep -l "$rutaQcc/$paqueteBuscado" | xargs grep -l "ERROR \[" | cut -f 9 -d "/" > $rutaTemporales/logsErrores.log;
while read equipoBusqueda; do
while read logBusqueda; do
grep "ERROR \[$equipoBusqueda\]" $rutaTrazas/$logBusqueda >> $rutaTemporales/erroresPendientes.log
if [ $? -eq 0 ];then
break;
fi;
done <$rutaTemporales/logsErrores.log
done <$rutaTemporales/lanzados_a_pendientes.log
cat $rutaTemporales/erroresPendientes.log | sed 's/ / /g' | sed '/No se ha podido/d' |
cut -f 7-14 -d " " | sort -u > $rutaTemporales/erroresPendientes_Final.log;
最終找到,grep,sed,cut等命令可以簡化。
您正在將整個文件讀入shell變量,然后通過單獨的剪切過程提取每一行。 這是非常低效的。
很難理解您要做什么。 也許您可以將函數替換為以下內容:
$ cd $rutaTrazas
$ sed 's/^/ERROR \[/; s/$/\]/' $rutaTemporales/lanzados_a_pendientes.log > search_strings
$ xargs grep -F -f search_strings \
< $rutaTemporales/logsErrores.log \
>> $rutaTemporales/erroresPendientes.log
$ < $rutaTemporales/erroresPendientes.log \
sed 's/ / /g' | sed '/No se ha podido/d' |
cut -f 7-14 -d " " |
sort -u > $rutaTemporales/erroresPendientes_Final.log
由於沒有語料或樣本輸出顯示您實際上要解析的內容,因此幾乎不可能弄清楚您實際上在做什么。 但是,您可以將此問題歸結為低效的處理和流程分叉。
日志文件通常是面向記錄的,其中每一行都是具有多個字段的記錄。 如果這是您的用例,那么AWK(或處於AWK仿真模式下的Perl / Ruby)通常是適合此工作的工具。 這樣可以確保每行僅處理一次,並且讀取行和拆分字段非常有效。
例如,使用Bash 4和GNU awk(aka gawk):
shopt -s globstar
awk 'BEGIN {error_count = 0}
/ERROR/ {print $9; ++error_count}
# other pattern/action pairs
END {print "Total errors:", error_count}
' **/instala_sw_qcc_2012* > /path/to/output/file
您可以將多個模式匹配應用於每行,或者如果確實需要這樣做,則可以從awk內部將輸出直接定向到單個文件。 但是,通過讓awk在一個進程中處理循環和行解析,您可能會獲得很大的效率。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.