2012-10-30 132 views
1

我有下面這個腳本將被守護進程並觸發可能數百,如果不是不同的用戶數千次。bash腳本優化

該腳本使用inotifywait觀看上傳文件夾,然後將上傳的文件移動到其最終目的地以進行演示,在旋轉(備份/移動)之前的上傳之後。該代碼將針對不同的上傳文件夾運行。

#!/bin/bash 

db="$VAR1"/path/to/upload/folder/ 
s3="$VAR2"/path/to/remote/folder 

inotifywait -m -r -e attrib "$db" | 
while read dir ev file; 
do 

     for dirnum in $(cd "$s3"; ls */*.png | sed 's%/.*%%' | sort -nr) 
     do 
       next=$(($dirnum + 1));      
       mv "$s3/$dirnum/post$dirnum.png" "$s3/$next/post$next.png"; 
     done 

     mv "$db"/"$file" "$s3"/1/post1.png 

done 

我能做些什麼來優化它?還是應該重寫一個更快的編程語言?另外,如何在一定的負載下測試腳本?

+0

如果速度夠快,則不需要重寫。你可以通過向其中扔文件來測試它。一個明顯的優化是跟蹤每個目錄中的計數(WTF是「文件夾」?),而不是每次計算它。 –

+0

相關,但擴展名爲[什麼是正確的方式來循環此?](http://stackoverflow.com/questions/13097606/whats-the-correct-way-to-loop-this/) –

回答

1

這不會給相同的行爲,但它避免了排序:

#!/bin/bash 

db="$VAR1"/path/to/upload/folder/ 
s3="$VAR2"/path/to/remote/folder 

inotifywait -m -r -e attrib "$db" | 
while read dir ev file; 
do 
    dirnum=1 
    while test -e "$s3/$dirnum"; do : $((dirnum += 1)); done 
    while test $dirnum -gt 0; do 
     next=$((dirnum + 1));  
     mkdir -p $s3/$next     
     mv "$s3/$dirnum/post$dirnum.png" "$s3/$next/post$next.png" 
     : $((dirnum -= 1)) 
    done 
    mv "$db/$file" "$s3"/1/post1.png 
done 

如果跟蹤存儲到$s3數量最多的,你可以避免第一個 循環。如果其他進程在$s3中創建文件 ,則這樣做會稍微脆弱一些,但在這種情況下,即使在這種簡單化的解決方案中,也存在爭用條件。 不重命名文件會簡單很多,但是將第一個文件上傳到 $s3/1,然後將第一個文件上傳到$s3/2。在這種情況下,腳本可以寫成:

#!/bin/bash 

db="$VAR1"/path/to/upload/folder/ 
s3="$VAR2"/path/to/remote/folder 
dirnum=1 
while test -e "$s3/$dirnum"; do : $((dirnum += 1)); done 
inotifywait -m -r -e attrib "$db" | 
while read dir ev file; 
do 
    mkdir -p "$s3"/$dirnum 
    mv "$db/$file" "$s3"/$dirnum/post$dirnum.png 
    : $((dirnum += 1)) 
done 
+0

第一個腳本比我的原始文件快得多,並且它能夠完成它應該做的事情,將舊文章移動到下一個編號的目錄。注意:在$ S3中創建文件的唯一過程就是這個腳本..將會有一個$ S4,$ S5等等,但是腳本中的哪個位置會開始迭代目錄$ S3/101?第二個腳本很吸引人,但它將上傳的文章放在$ S3/107目錄中,然後下一個上傳文件在$ S3/108上,最新的上傳文件必須總是在$ S3/1中,而在S3/2中則是最新的上傳文件。 ..感謝您的優化課程。生病了跟你發佈的第一個劇本! – sirvon

+1

第一個inner while循環把dirnum遞增到第一個非現存目錄(在你的情況下顯然是101)。 –

0

你可以重構你的腳本是這樣的:

!/bin/bash 

db="$VAR1"/path/to/upload/folder/ 
s3="$VAR2"/path/to/remote/folder 

while read dir ev file 
do 
    while read dirnum 
    do 
     next=$(($dirnum + 1)) 
     mv "$s3/$dirnum/post$dirnum.png" "$s3/$next/post$next.png" 
    done < <(find "$s3" -depth 2 -name "*.png" -exec dirname {} \; | sort -unr) 

    mv "$db"/"$file" "$s3"/1/post1.png 

done < <(inotifywait -m -r -e attrib "$db") 
1

你應該避免走動這麼多的文件,通過將新的文件在新的目錄,並只留下舊文件舊目錄。您可能需要反轉您的演示邏輯,因此會顯示最新的文件(最大編號),而不是每次都顯示post1.png。但是,通過讓事情少得多,你可以加快速度 - 並且通過讓事情保持原有狀態,讓事情更輕鬆。

如果速度不夠快,加快速度的最好方法之一是退後一步,看看算法,看看是否有一個可以使用的基本上更快的算法。如果您已經在使用最佳算法,那麼您可以查看如何加快速度的細節,但有時您可以通過重新評估算法來獲得數量級的提高,其中調整可能會使速度提高一倍。

+0

ty理解。移動東西是瓶頸。我現在被迫讓前鋒像後衛一樣充滿活力!我喜歡進步。我沒有意識到我正在設計一個算法。我的眼睛是開放的。 – sirvon