仅在上一个完成时才运行一个进程。重击

时间:2019-03-22 10:31:56

标签: bash shell directory filesystems aria2

我正在使用aria2下载一些数据,并带有选项--on-download-complete以自动运行bash脚本来处理数据。

aria2c --http-user='***' --http-passwd='***' --check-certificate=false --max-concurrent-downloads=2 -M products.meta4 --on-download-complete=/my/path/script_gpt.sh

关注我的bash脚本

#!/bin/bash

oldEnd=.zip
newEnd=_processed.dim

for i in $(ls -d -1 /my/path/S1*.zip)
do
if [ -f ${i%$oldEnd}$newEnd ]; then 
   echo "Already processed"
else
   gpt /my/path/graph.xml -Pinput1=$i -Poutput1=${i%$oldEnd}$newEnd
fi
done 

基本上,每次下载完成时,都会启动for循环。首先,它检查下载的产品是否已被处理,如果没有,它将运行特定任务。

我的问题是,每次下载完成时,都会运行bash脚本。这意味着,如果从上次运行bash脚本起就没有完成分析,那么这两个任务将重叠并占用我所有的内存资源。

理想情况下,我想:

  • 每次运行bash脚本时,请检查是否还有正在进行的进程。

  • 如果是这样,请等到完成后再运行

这就像创建一个任务队列(例如在for循环中,其中每次迭代都等到上一个完成为止)。

我尝试用wait来实现solutin或识别PID,但没有成功。

也许会改变方法,而不是使用aria2处理刚刚下载的数据,而是实施另一种解决方案?

1 个答案:

答案 0 :(得分:2)

您可以尝试获取排他文件锁定,并且仅在释放该锁定时运行。您的代码可能类似于

#!/bin/bash

oldEnd=.zip
newEnd=_processed.dim

{
    flock -e 200

    while IFS= read -r -d'' i
    do
        if [ -f "${i%$oldEnd}$newEnd" ];
        then 
            echo "Already processed"
        else
            gpt /my/path/graph.xml -Pinput1="$i" -Poutput1="${i%$oldEnd}$newEnd"
        fi
    done < <(find /my/path -maxdepth 1 -name "S1*.zip" -print0)
} 200> /tmp/aria.lock

此代码打开针对文件描述符200的排他锁(我们告诉bash打开该文件以将输出重定向到锁定文件,并阻止其他脚本执行代码块,直到关闭文件。)代码块完成后立即关闭,允许其他等待的进程继续执行。

顺便说一句,您应始终引用变量,并且应避免解析ls输出。另外,为避免出现空格和意外滚动问题,输出用零分隔的文件列表并用read进行读取是避免这些问题的一种方法。