我正在使用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
或识别PID
来实现解决方案,但没有成功。
也许改变方法,而不是使用aria2
来处理刚刚加载的数据,而是实施另一种解决方案?
您可以尝试获取独占文件锁,并且仅在释放锁时运行。你的代码可能像
#!/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
读取它是避免这些问题的一种方法。