0

我正在使用自动运行脚本来处理数据aria2的选项来下载一些数据。--on-download-completebash

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或识别出解决方案,PID但没有成功。

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

4

1 回答 1

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是避免这些问题的一种方法。

于 2019-03-22T14:05:01.323 回答