2015-06-04 2 views
2

У меня есть сценарий, который я написал для сканирования каталога текстовых файлов, и если он находит их, он создает системный вызов для запуска скрипта в txt-файле. Я все еще работаю над несколькими небольшими ошибками, из-за которых некоторые из моих системных вызовов терпят неудачу. Однако я хотел бы, чтобы это НЕ убило мой скрипт. Я просто хотел бы получить информацию об ошибке, а затем продолжить свою жизнь. Кажется, что любой успешный вызов возвращает 0, а любой вызов, который привел к ошибке, возвращает n. Я попытался сравнить результат с 0, но он так и не дошел. Любые предложения о том, как я могу это сделать?Продолжающийся скрипт после сбоя на os.system вызов python

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:]) 
+2

Вы можете посмотреть в попытке кроме этого – LampPost

+0

Зачем использовать 'os' в первую очередь, если ваш цикл в Python и скрипт в Python? – physicalattraction

ответ

2

Вы должны использовать модуль подпроцесс в частности check_call, ловя CalledProcessError который будет поднят для любого ненулевого состояния выхода:

from subprocess import check_call,CalledProcessError  

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

Не так легко следовать код, я бы предлагайте не вложить все остальные функции в основном. Я хотел бы также использовать glob найти файлы ТХТЫ:

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) 
+0

Отлично работает! – kennedyl

+0

@kennedyl, no prob, вы действительно должны всегда регистрировать ошибки или, по крайней мере, распечатывать их, а не просто игнорировать их, ответ ниже предлагает использовать Popen, который не будет ждать кода возврата и использовать shell = True обычно не является хорошим идея. –

+0

У меня все работает. Приносим извинения за трудный для чтения код раньше и спасибо за вашу помощь. Я имею тенденцию модулировать свой код, когда у меня есть функциональность. Ниже мой конечный продукт. Мне любопытно, однако, какая польза от glob по сравнению с моей реализацией? – kennedyl

0

Ловить ошибки и выходы без остановки вашего основного процесса, я предлагаю использовать подпроцесс модуль.

import subprocess 

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

Не уверен насчет голосов. check_call необходим только в том случае, если вы хотите создать исключение. Основной код, запускающий popen, будет продолжать свою жизнь, даже если дочерний процесс возвращает ненулевой код. Посмотреть этот пост: http://stackoverflow.com/questions/15316398/check-a-commands-return-code-when-subprocess-raises-a-calledprocesserror-except –

0
  1. Если вы звоните, чтобы вызвать питон скрипт, вы должны учитывать, что интегрировать в свою собственную программу питона.
  2. В противном случае вы должны использовать модуль подпроцесса, это рекомендуется в документации на python, как показано в os.system. В документации также предлагается написать замену таким образом substitute for os.system. См. Раздел 17.1.4.3. как поймать исключение.
0

Мое текущее решение:

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:])