【问题标题】:Continuing script after failure on os.system call pythonos.system调用python失败后继续脚本
【发布时间】:2015-06-04 16:41:30
【问题描述】:

我编写了一个脚本来扫描文本文件的目录,如果找到它们,它会创建一个系统调用来在 txt 文件上运行脚本。我仍在处理一些导致我的一些系统调用失败的小错误。但是,我希望这不会杀死我的脚本。我只想知道错误然后继续我的生活。似乎任何成功的调用都返回 0,而任何导致错误的调用都返回 n。我试图将结果与 0 进行比较,但它永远不会那么远。关于我如何做到这一点的任何建议?

import sys, getopt, os

def main(argv):

    def scan_dir(path):
            temp_path = path
            print temp_path
            for file in os.listdir(path):
                    temp_path += file
                    if file.endswith(".txt"):
                            result = os.system("python callscript.py -i %s" % path)
                            if result != 0
                                    print "Error!"

                    temp_path = path


    def usage():
            print "usage:  dostuff.py [hi:]\n \
                  \t -h\t print usage\n \
                  \t -i\t directory path\n"
            sys.exit(2)

    if(len(argv) == 0):
            usage()

    path = ''

    try:
            opts, args = getopt.getopt(argv,"hi:",["path="])
    except getopt.GetoptError:
            usage()

    for opt, arg in opts:
            if opt == '-h':
                    usage()

            elif opt in ("-i", "--ipath"):
                    path = arg
    if path.endswith('/') == False:
            path += '/'

    scan_dir(path)



if __name__ == "__main__":
main(sys.argv[1:])

【问题讨论】:

  • 你可以试试看,除了这个
  • 如果您的循环在 Python 中并且脚本在 Python 中,为什么首先使用 os?

标签: python os.system


【解决方案1】:

您应该使用子进程模块,尤其是 check_call,捕获一个 CalledProcessError,对于任何非零退出状态都会引发该模块:

 from subprocess import check_call,CalledProcessError      

  try:
       check_call(["python", "callscript.py", "-i",path])
  except CalledProcessError as e:
       print e.message

遵循您的代码并不容易,我建议不要将所有其他函数嵌套在 main 中。我也会使用glob 来查找txt 文件:

from glob import  glob

def scan_dir(path):
    files = (os.path.join(path,f) for f in glob(os.path.join(path,"*.txt")))
    for fle in files:    
        try:
            check_call(["python", "callscript.py", "-i", fle])
        except CalledProcessError as e:
            print e.message

def usage():
    print "usage:  dostuff.py [hi:]\n \
          \t -h\t print usage\n \
          \t -i\t directory path\n"
    sys.exit(2)


if __name__ == "__main__":
    args = sys.argv[1:]
    if not args:
        usage()
    path = ''
    try:
        opts, args = getopt.getopt(args, "hi:",["path="])
    except getopt.GetoptError:
            usage()

    for opt, arg in opts:
        if opt == '-h':
                usage()
        elif opt in ("-i", "--ipath"):
                    path = arg
    if not path.endswith('/'):
            path += '/'
    scan_dir(path)

【讨论】:

  • @kennedyl,没有问题,你真的应该总是记录错误或至少打印出来而不是忽略它们,下面的答案建议使用不会等待返回码的 Popen 并使用 shell =True 通常不是一个好主意。
  • 一切正常。对于之前难以阅读的代码,我深表歉意,并感谢您的帮助。一旦有了功能,我倾向于模块化我的代码。下面是我的最终产品。不过,我很好奇,glob 对我的实现有什么好处??
  • 感谢您的回答。我知道我必须进行异常处理,但不知道是什么。现在我不必监视我的脚本并重新启动它们。
【解决方案2】:
  1. 如果您要调用 Python 脚本,则应考虑将其集成到您自己的 Python 程序中。
  2. 否则,您应该使用 subprocess 模块,这是在 python 文档中推荐的,如os.system 所示。该文档还建议以这种方式编写替换substitute for os.system。请参阅第 17.1.4.3 节。了解如何捕获异常。

【讨论】:

    【解决方案3】:

    要在不停止主进程的情况下捕获错误和输出,我建议使用 subprocess 模块。

    import subprocess
    
    processToRun = "python callscript.py -i %s" % path
    proc = subprocess.Popen (processToRun, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    print(proc.returncode)
    

    【讨论】:

    • 不确定这里的否决票。仅当您想要抛出异常时才需要 check_call 。即使子进程返回非零代码,运行 popen 的主代码也会继续运行。请参阅其他帖子:stackoverflow.com/questions/15316398/…
    【解决方案4】:

    我目前的解决方案:

    import sys, getopt, os    
    from subprocess import check_call, CalledProcessError
    
    
    def scan_dir(path):
    
        fail_count = 0
        success = []
        failure = []
    
        temp_path = path
        print temp_path
        for file in os.listdir(path):
                temp_path += file
                if file.endswith(".txt"):
                        try:
                                check_call(["python", "callscript.py","-i", temp_path])
                                success.append(file)
                        except CalledProcessError as e:
                                print e.message
                                failure.append(file)
                                fail_count += 1
                                continue
                temp_path = path
    
        if fail_count > 0:
                f = open("log.txt", "w")
                print ("%d Errors occurred during conversion. Check log.txt for details" % fail_count)
                f.write("The following files were successfully converted:\n")
                for s in success:
                        f.write("\t-%s\n" % s)
    
                f.write("\n\nThe following files failed to be converted:\n")
                for a in failure:
                        f.write("\t-%s\n" % a)
                f.close()
        else:
                print "All files converted successfully!"
    
    
    def usage():
        print "usage:  dostuff.py [hi:]\n \
              \t -h\t print usage\n \
              \t -i\t directory path\n"
        sys.exit(2)
    
    def main(argv):
    
        if(len(argv) == 0):
                usage()
    
        path = ''
    
        try:
                opts, args = getopt.getopt(argv,"hi:",["path="])
        except getopt.GetoptError:
                usage()
    
        for opt, arg in opts:
                if opt == '-h':
                        usage()
    elif opt in ("-i", "--ifile"):
                        path = arg
        if path.endswith('/') == False:
                path += '/'
    
        scan_dir(path)
    
    
    if __name__ == "__main__":
        main(sys.argv[1:])
    

    【讨论】:

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