bash脚本优化

时间:2012-10-30 03:29:09

标签: bash optimization

我在下面的这个脚本将被守护,并且可能被不同的用户触发数百次,甚至数千次。

脚本使用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

我可以做些什么来优化它?或者它应该重写更快的编程语言?另外,如何在一定量的负载下测试脚本?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

通过将新文件放在新目录中并将旧文件留在旧目录中,您应该避免移动这么多文件。您可能需要反转您的表示逻辑,因此每次都会显示最新文件(最大数字),而不是post1.png。但是你可以通过降低成本来提高速度 - 并且通过让它完全离开已经存在的东西来让它做得更少。

如果某些内容不够快,加快速度的最佳方法之一是退后一步查看算法,看看是否有一个基本上更快的算法可以使用。如果您已经在使用最优算法,那么您可以查看如何加快速度的详细信息,但有时您可以通过重新访问算法来获得数量级的改进,在这种情况下,调整可能只会使速度提高一倍。 / p>

答案 2 :(得分: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")