我正在使用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
处理刚刚下载的数据,而是实施另一种解决方案?
答案 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
进行读取是避免这些问题的一种方法。