1

我在下面有这个脚本,它将被不同的用户守护和触发数百甚至数千次。

该脚本用于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

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

4

3 回答 3

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
于 2012-10-30T04:48:15.533 回答
1

您应该通过将新文件放在新目录中并将旧文件单独留在旧目录中来避免移动太多文件。您可能需要反转您的演示逻辑,以便显示最新的文件(最大的数字),而不是post1.png每次。但是你可以通过减少它的工作来加快它的速度——你可以通过让它离开已经存在的东西来减少它的工作量。

如果某些东西不够快,加速它的最佳方法之一是退后一步,看看算法,看看是否有一个从根本上更快的算法可以使用。如果您已经在使用最佳算法,那么您可以查看如何加速该算法的详细信息,但有时您可以通过重新访问该算法获得数量级的改进,其中调整可能会使您的速度仅翻倍。

于 2012-10-30T05:50:08.723 回答
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")
于 2012-10-30T04:10:01.037 回答