[英]Bash Script is super slow
我正在更新一個舊腳本來解析ARP數據並從中獲取有用的信息。 我們添加了一個新的路由器,雖然我可以從路由器中提取ARP數據,但它是一種新的格式。 我有一個文件“zTempMonth”,它是來自兩組路由器的所有arp數據,我需要編譯成一個規范化的新數據格式。 下面的代碼行按邏輯方式執行我需要它們 - 但它非常慢 - 因為在以前腳本需要20-30分鍾的情況下運行這些循環需要幾天時間。 有沒有辦法加快速度,或者找出減慢速度的方法?
先感謝您,
echo "Parsing zTempMonth"
while read LINE
do
wc=`echo $LINE | wc -w`
if [[ $wc -eq "6" ]]; then
true
out=$(echo $LINE | awk '{ print $2 " " $4 " " $6}')
echo $out >> zTempMonth.tmp
else
false
fi
if [[ $wc -eq "4" ]]; then
true
out=$(echo $LINE | awk '{ print $1 " " $3 " " $4}')
echo $out >> zTempMonth.tmp
else
false
fi
done < zTempMonth
>>
( open(f, 'a')
)循環中的調用很慢。 只需輸掉#2和#3,你就可以加快速度並保持純粹的狂歡:
#!/usr/bin/env bash
while read -a line; do
case "${#line[@]}" in
6) printf '%s %s %s\n' "${line[1]}" "${line[3]}" "${line[5]}";;
4) printf '%s %s %s\n' "${line[0]}" "${line[2]}" "${line[3]}";;
esac
done < zTempMonth >> zTempMonth.tmp
但如果有多行,這仍然比純awk慢。 考慮一個像這樣簡單的awk腳本:
BEGIN {
print "Parsing zTempMonth"
}
NF == 6 {
print $2 " " $4 " " $6
}
NF == 4 {
print $1 " " $3 " " $4
}
你可以像這樣執行它:
awk -f thatAwkScript zTempMonth >> zTempMonth.tmp
獲得與當前腳本相同的附加方法。
編寫shell腳本時,直接調用函數而不是使用子shell調用函數幾乎總是更好。 我見過的通常慣例是回顯函數的返回值並使用子shell捕獲該輸出。 例如:
#!/bin/bash
function get_path() {
echo "/path/to/something"
}
mypath="$(get_path)"
這樣可以正常工作,但是使用子shell有很大的速度開銷,而且有更快的替代方案。 相反,你可以只有一個約定,其中一個特定的變量總是函數的返回值(我使用retval)。 這還有一個額外的好處,也允許您從函數返回數組。
如果您不知道子shell是什么,為了本博客文章的目的,子shell是另一個bash shell,只要您使用$()
或``並且用於執行您放入的代碼,就會生成它。
我做了一些簡單的測試,讓你觀察開銷。 對於兩個功能相同的腳本:
這個使用子shell:
#!/bin/bash
function a() {
echo hello
}
for (( i = 0; i < 10000; i++ )); do
echo "$(a)"
done
這個使用變量:
#!/bin/bash
function a() {
retval="hello"
}
for (( i = 0; i < 10000; i++ )); do
a
echo "$retval"
done
這兩者之間的速度差異顯着且顯着。
$ for i in variable subshell; do
> echo -e "\n$i"; time ./$i > /dev/null
> done
variable
real 0m0.367s
user 0m0.346s
sys 0m0.015s
subshell
real 0m11.937s
user 0m3.121s
sys 0m0.359s
如您所見,使用variable
,執行需要0.367秒。 但是,子shell需要整整11.937秒!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.