从Popen调用时从unix命令处理错误

时间:2013-10-24 04:26:29

标签: python multithreading unix

我有以下方法用于测试bc unix命令...它接受一个表达式,执行它并取回输出...

def run_test(expr=""):

        try:
            process = sp.Popen('bc',
                               stdin=sp.PIPE,
                               stdout=sp.PIPE,
                               stderr=sp.PIPE)
            process.stdin.write(expr)
            result = process.stdout.readline()
            process.stdin.close()
            retval = process.wait()
            return result
        except Exception, e:
            print e


# correct expression, returns '4'
print run_test('2+2\n') 

但是,当我传递错误的表达式expr时,我想正确处理错误,因此我可以断言测试用例expr正确失败...

#never stops
print run_test('2 / 0\n')

但是,上面的表达式永远不会返回...我想返回一个值,例如false,它会告诉我表达式无效,然后当我断言时,

assertTrue(run_test('2 / 0\n'), False) 

会正常工作......我怎么能实现呢?

2 个答案:

答案 0 :(得分:1)

正在发生的事情是stderr没有被正确重定向。在执行readline时,需要通过python提示符中的以下命令将stderr重定向到stdout。你需要将它移动到你的功能。

   def run_test(expr=""):

        try:
            process = sp.Popen('bc',
                               stdin=sp.PIPE,
                               stdout=sp.PIPE,
                               stderr=sp.STDOUT)
            process.stdin.write(expr)
            result = process.stdout.readline()
            process.stdin.close()
            retval = process.wait()
            return result
        except Exception, e:
            print e


# correct expression, returns '4'
print run_test('2+2\n') 

print run_test('2 / 0\n') # now this stops too

文档说:http://docs.python.org/2/library/subprocess.html 可以用作Popen的stderr参数的特殊值,表示标准错误应该与标准输出进入相同的句柄。

答案 1 :(得分:0)

  1. 你最好的选择是在python中实际做某事 程序永远不能保证返回合理的东西。

  2. 接下来最好是避免以交互模式调用程序 仅在命令行模式下。

  3. 之后,您可以尝试始终为您正在呼叫的程序添加退出,例如对于bc使用process.stdin.write(expr + "\nquit\n")

  4. 最后和最差的是启动一个计时器,如果表达式在计时器到期之前没有终止,则终止进程并给出超时错误。