我是很长时间的SO读者,但这是我的第一个问题 我正在编写一个Python 3程序(我目前正在自学)来编译和运行一组C ++程序,这些程序应该做同样的事情(学生提交作业的提交)和将它们的输出与我在文本文件中已有的预期输出进行比较。
我正在寻找一种方法来运行这些允许我执行的可执行文件:
到目前为止我尝试的所有内容(从类似问题的答案中)都缺少了一些东西。我无法找到满足我所有需求的(上述各点)。 以下是一些例子:
check_output()(如在this问题中)如果可执行文件崩溃,则不收集输出,并且某些消息(如核心转储)仍然会进入屏幕。
Popen()(如this中所示)似乎不会终止可执行文件(超出时间时)。 python线程结束(我希望我在这里使用正确的术语),但可执行文件继续运行。
尽管不鼓励像 os.system()这样的方法,但无论如何我都尝试了它们,但它们并没有做得更好。
如果有人能指出我实现这一目标的方法,我会非常感激。我为任何语法错误道歉,因为英语不是我的第一语言。如果需要进一步的细节,请告诉我。 谢谢,
编辑:
这是我的python代码的最小副本:
from subprocess import STDOUT, check_output, TimeoutExpired
timeLimit = 3 # seconds
strOutput = ''
try:
output = check_output('./a.out', stderr = STDOUT, timeout = timeLimit)
strOutput = ''.join(map(chr, output))
except TimeoutExpired as e:
strOutput += 'Error: Time limit exceeded, terminated..'
except Exception as e:
strOutput += 'Error: ' + str(e)
f = open('report.txt','w')
f.write(strOutput)
f.close()
我还包括一些C ++示例,其中包含一些错误,用于创建用于测试先前代码的可执行文件。 它们都可以编译为: g ++ programName.cpp
#include <iostream>
using namespace std;
int main()
{
cout << "This one is working correctly!" << endl;
}
以下代码导致&#34;除以零&#34;错误。 check_output()
未捕获此错误之前打印的语句#include <iostream>
using namespace std;
int main()
{
cout << "Trying to divide by zero.." << endl;
cout << 3 / 0 << endl;
}
此代码等待意外输入(应在指定的超时后由脚本终止)
#include <iostream>
using namespace std;
int main()
{
int x;
cout << "Waiting for an unexpected input.." << endl;
cin >> x;
}
我无法找到重现核心转储问题的可靠方法。核心转储是一个特例,因为 check_output()无法捕获其输出(它直接/仅直接进入屏幕)。
P.S。我无法添加标签&#39; check_output()&#39;,我没有足够的声誉。
答案 0 :(得分:0)
一个简单的解决方案可能是使用到目前为止找到的所有解决方案,但不是一次运行程序,而是多次运行它们。
一次,确定运行时间, 另一次,确定输出 等等 这样,您还可以测试是否给出相同的输入它们提供相同的输出。 它可能不是您正在寻找的“超级优雅”解决方案,但它现在可能已经足够了,直到您在python中找到子进程的圣杯。
另外,您可以将输出重定向到文件以获得部分结果+超时,然后读取文件以获得部分结果。
答案 1 :(得分:0)
基于@CharlesDuffy注释,我简化了流程树以使其更平坦,并切换到subprocess.call()
,这具有捕获&#34;部分&#34;输出(在可执行文件崩溃之前)
核心转储但subprocess.call()
仍未捕获,它会进入屏幕。
有没有办法捕获核心转储的输出?或至少阻止它在屏幕上显示?
from subprocess import call, TimeoutExpired
timeLimit = 3 # seconds
errMsg = ''
ret_code = 0
f = open('report.txt','w')
try:
ret_code = call('./a.out', stdout = f, stderr = f, timeout = timeLimit)
except TimeoutExpired as e:
errMsg = 'Error: Time limit exceeded, terminating..'
except Exception as e:
errMsg = 'Error: ' + str(e)
if ret_code:
errMsg = 'Error: ' + str(ret_code)
f.write(errMsg)
f.close()