【问题标题】:Keep track of execution time in a bash script and terminate current command if it takes too long跟踪 bash 脚本中的执行时间并在执行时间过长时终止当前命令
【发布时间】:2016-10-18 00:54:05
【问题描述】:

我正在尝试创建一个 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 让我重新登录。

这很好用,我可以从中获取数千个文件。但是会发生什么——要么我的路由器宕机一两秒钟,要么他们的网站宕机一两分钟,curl 就会坐在那里,以为它正在下载几个小时。我曾经回过头来,实际上花了 24 小时在同一个文件上。它似乎没有能力知道传输是否在中间超时 - 只有当它无法开始传输时。

我知道如果将命令与“sleep”结合使用,有多种方法可以终止命令的执行,但由于这必须是“智能”并从停止的地方重新启动,所以我不能直接杀死整个脚本。

有什么建议吗?如果我可以使用 curl 通过终端命令登录,我愿意使用除 curl 之外的其他东西。

【问题讨论】:

  • 一种直接的方法是设置相当于事件循环的内容并将命令生成为子shell。在您的循环中,定期检查任务是否已完成,并在必要时在时间过长时终止它们。
  • @DavidHoelzer 您可能是指后台作业(在命令末尾以控制操作员& 开头),而不是subshel​​ls。跨度>
  • 我不知道你可以用 shell 脚本做到这一点,但是用 python 和 requests 会很简单。
  • 好吧,这里的问题是,如果下载失败,我必须让它真正重试下载。类似于“cookie 不起作用”部分,只是它会说“下载超时”并从 i-1 重试。这是最难的部分,让它与其余的逻辑一起工作!

标签: linux bash curl


【解决方案1】:

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

来自手册:

--最大时间

允许整个操作花费的最长时间(以秒为单位)。这对于防止您的批处理作业因网络速度慢或链接中断而挂起数小时很有用。从 7.32.0 开始,此选项接受十进制值,但实际超时的准确性会随着指定超时的十进制精度增加而降低。另请参阅 --connect-timeout 选项。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-24
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    相关资源
    最近更新 更多