2012-10-30 111 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