简体   繁体   English

python 2.x:有条件地捕获异常(如果文件丢失,请忽略忽略清理)

[英]python 2.x:Conditionally Catching Exceptions (Ignore gracefully cleanup if the file is missing)

I am having a script which cleanups the logs older than 14 days at a shared location. 我有一个脚本可以在共享位置清理超过14天的日志。 Now this script can run at same time from different host. 现在,该脚本可以在不同主机上同时运行。 In a particular situation if two or more hosts try to cleanup same file, only one will succeed and all other gives error "No such file or directory". 在特定情况下,如果两个或更多主机尝试清除同一文件,则只有一个主机将成功,而其他所有主机都将给出错误“无此文件或目录”。 How can I update the code to Ignore gracefully cleanup if the file suddenly goes missing. 如果文件突然丢失,如何更新代码以忽略正常清理。 Below is part of code which is performing the cleanup. 以下是执行清理的部分代码。 count tracks the number of files deleted. count跟踪删除的文件数。

if os.stat(filename).st_mtime < current_time - 14 * 86400:
    try:
       os.remove(filename)
       count += 1
    except:
       logger.warning("Not able to delete the file %s" % filename)

One way is to "pass" the exception if file dont exist but continue to log warning if you are not able to delete the file. 一种方法是在文件不存在的情况下“传递”异常,但在无法删除文件的情况下继续记录警告。 How to include this condition. 如何包括此条件。

As @Mark suggests you could check beforehand if the file exists and then delete it but there is still a potential race condition in such an approach. 正如@Mark建议的那样,您可以事先检查文件是否存在,然后将其删除,但是这种方法仍然存在潜在的竞争状况。 It can occur between script's instances after os.stat and before os.remove . 它可以在os.stat之后和os.remove之前的脚本实例之间发生。 Moving all of the code raising errors to try / except should do the job. 将所有引发错误的代码移至try / except ,即可完成这项工作。 However, as I understand there is a problem with logging a truthful message. 但是,据我了解,记录真实消息存在问题。 Additional flag attempted_delete should help with that: 附加标志attempted_delete应该可以帮助您:

attempted_delete = False
try:
    if os.stat(filename).st_mtime < current_time - 14 * 86400:
         os.remove(filename)
         count += 1
         attempted_delete = True
except:
     if attempted_delete:
         logger.warning("Not able to delete the file %s" % filename)

An except clause with no exception (type) list is a catch-all: easy to setup but hard to use. 一个没有异常(类型)列表的except子句是一个万能的:易于设置但很难使用。 Here you should specifically catch (and ignore) a FileNotFoundError and log any other exception: 在这里,您应该专门捕获(并忽略) FileNotFoundError并记录任何其他异常:

try:
   if os.stat(filename).st_mtime < current_time - 14 * 86400:
      os.remove(filename)
      count += 1
except FileNotFoundError:
   pass  # file has already been deleted: all is fine
except:
   logger.warning("Not able to delete the file %s" % filename)

Above was for Python 3, as you use Python 2, you can only check for OSError and then control its errno attribute: 上面是针对Python 3的,当您使用Python 2时,您只能检查OSError然后控制其errno属性:

try:
   if os.stat(filename).st_mtime < current_time - 14 * 86400:
      os.remove(filename)
      count += 1
except OSError as e:
   if e.errno != errno.ENOENT:
      # do not log if file has already been deleted
      logger.warning("Not able to delete the file %s" % filename)
except:
   logger.warning("Not able to delete the file %s" % filename)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM