2016-10-18 53 views
0

我试图创建一个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以外的内容。

+0

一个简单的方法是设置相当于一个事件循环,并将命令产生为子shell。在你的循环中,定期检查任务是否完成,如果有必要的话,如果过了很多时间就终止它们。 –

+0

@DavidHoelzer你可能是指_background jobs_(在命令的末尾用控制运算符'&开始),而不是_subshel​​ls_。 – mklement0

+0

我不知道你可以用shell脚本来做到这一点,但是对于python和请求来说这是完全简单的。 –

回答

0

您可以尝试使用卷曲选项--connect-timeout--max-time--max-time应该是你的选择。

从手册:

--max时间

最大时间,你让整个操作需要几秒钟。由于网络速度较慢或链接断开,这对于防止批量作业挂起数小时很有用。自7.32.0版本开始,此选项接受十进制值,但实际超时的准确度会降低,因为指定的超时会以十进制精度增加。另请参阅--connect-timeout选项。

如果多次使用此选项,将使用最后一个。

然后在var中捕获该命令的结果并根据结果进一步处理。