我试图创建一个bash脚本来从某个网站下载文件。在bash脚本中记录执行时间并在需要太长时间时终止当前命令
他们的下载链接是连续的 - 例如,它只是id = 1,id = 2,id = 3一直到660000.唯一的要求是你必须登录,这使得这有点困难。哦,并且登录将在几个小时后随机超时,因此我必须重新登录。
这是我当前的脚本,它在99%的时间内运行良好。
#!/bin/sh
cd downloads
for i in `seq 1 660000`
do
lastname=""
echo "Downloading file $i"
echo "Downloading file $i" >> _downloadinglog.txt
response=$(curl --write-out %{http_code} -b _cookies.txt -c _cookies.txt --silent --output /dev/null "[sample URL to make sure cookie is still logged in]")
if ! [ $response -eq 200 ]
then
echo "Cookie didn't work, trying to re-log in..."
curl -d "userid=[USERNAME]" -d "pwd=[PASSWORD]" -b _cookies.txt -c _cookies.txt --silent --output /dev/null "[login URL]"
response=$(curl --write-out %{http_code} -b _cookies.txt -c _cookies.txt --silent --output /dev/null "[sample URL again]")
if ! [ $response -eq 200 ]
then
echo "Something weird happened?? Response code $response. Logging in didn't fix issue, fix then resume from $(($i - 1))"
echo "Something weird happened?? Response code $response. Logging in didn't fix issue, fix then resume from $(($i - 1))" >> _downloadinglog.txt
exit 0
fi
echo "Downloading file $(($i - 1)) again incase cookie expiring caused it to fail"
echo "Downloading file $(($i - 1)) again incase cookie expiring caused it to fail" >> _downloadinglog.txt
lastname=$(curl --write-out %{filename_effective} -O -J -b _cookies.txt -c _cookies.txt "[URL to download files]?id=$(($i - 1))")
echo "id $(($i - 1)) = $lastname" >> _downloadinglog.txt
lastname=""
echo "Downloading file $i"
echo "Downloading file $i" >> _downloadinglog.txt
fi
lastname=$(curl --write-out %{filename_effective} -O -J -b _cookies.txt -c _cookies.txt "[URL to download files]?id=$i")
echo "id $i = $lastname" >> _downloadinglog.txt
done
所以基本上我把它做的是试图移动到下一个文件中的设置之前下载一个随机文件。如果下载失败,我们假设登录cookie不再有效,并告诉curl重新登录。
这很好,我可以从它得到几千个文件。但是会发生什么 - 无论是我的路由器停了一两秒钟,还是他们的网站都停了一两分钟,卷曲就会坐在那里,认为它会下载好几个小时。我曾经回过头来花费24小时在同一个文件上。它似乎没有能力知道转移是否在中间时间结束 - 只有当它不能开始转移时。
我知道如果将它与“睡眠”结合起来,有些方法可以终止命令的执行,但是因为这必须是“智能”并从停止的地方重新开始,所以我不能杀死整个脚本。
有什么建议吗?如果我可以使用它来通过终端命令登录,我愿意使用curl以外的内容。
一个简单的方法是设置相当于一个事件循环,并将命令产生为子shell。在你的循环中,定期检查任务是否完成,如果有必要的话,如果过了很多时间就终止它们。 –
@DavidHoelzer你可能是指_background jobs_(在命令的末尾用控制运算符'&开始),而不是_subshells_。 – mklement0
我不知道你可以用shell脚本来做到这一点,但是对于python和请求来说这是完全简单的。 –