![](/img/trans.png)
[英]How to catch Cntrl + C in a shell script which runs a Python script
[英]i want develop a python script which compiles and runs c programs using gcc
我想用Python編寫一個程序,該程序將C程序作為輸入,針對也作為輸入的測試用例執行它,並為每個測試用例打印輸出。 我正在使用Windows
我嘗試了subprocess.run,但它在運行時不接受輸入(即動態地)
from subprocess import *
p1=run("rah.exe",input=input(),stdout=PIPE,stderr=STDOUT,universal_newlines=True)
print(p1.stdout)
C代碼:
#include<stdio.h>
void main()
{
printf("Enter a number");
int a;
scanf("%d",&a);
for(int i=0;i<a;i++)
{
printf("%d",i);
}
}
python idle上的預期輸出:
Enter a number
5
01234
實際輸出:
5
Enter a number 01234
我同意@ juanpa.arrivillaga的建議。 您可以為此使用subprocess.Popen
和communicate()
:
import subprocess
import sys
p = subprocess.Popen('rah.exe', stdout=sys.stdout, stderr=sys.stderr)
p.communicate()
更新:上面的腳本在IDLE上不起作用,因為IDLE更改了IO對象sys.stdout, sys.stderr
,這破壞了fileno()
函數。 如果可能的話,應該將代碼放入python文件(例如script.py
),然后使用以下命令從Windows命令行運行它:
python script.py
否則,您可以通過輸入以下命令在Windows的命令行上執行類似於IDLE的操作:
python
這將啟動類似於IDLE的控制台,但不會更改IO對象。 在那里,您應該輸入以下行以獲得類似的結果:
import subprocess
import sys
_ = subprocess.Popen('rah.exe', stdout=sys.stdout,stderr=sys.stderr).communicate()
我嘗試了subprocess.run,但它在運行時不接受輸入(即動態地)
如果您不執行任何操作,則子進程將僅繼承其父級的stdin。
除此之外,由於您要攔截子流程的輸出並在以后進行打印,因此您不會在“預期的輸出”中獲得正在寫入的內容:輸入不會回顯,因此您只得到了所得到的寫入子進程的stdout,它們都是printfs。
如果要與子流程動態交互,則必須創建一個適當的Popen對象,用管道傳輸所有內容,並使用stdin.write()和stdout.read()。 而且因為您將不得不處理管道緩沖,所以這將是痛苦的。
如果您打算做很多事情,那么您可能需要看一下pexpect :“交互式”子流程幾乎就是面包和黃油。
關於作品:
from subprocess import Popen, PIPE
from fcntl import fcntl, F_GETFL, F_SETFL
from os import O_NONBLOCK
import select
p = Popen(['./a.out'], stdin=PIPE, stdout=PIPE)
fcntl(p.stdout, F_SETFL, fcntl(p.stdout, F_GETFL) | O_NONBLOCK)
select.select([p.stdout], [], [])
print(p.stdout.read().decode())
d = input()
p.stdin.write(d.encode() + b'\n')
p.stdin.flush()
select.select([p.stdout], [], [])
print(p.stdout.read().decode())
#include<stdio.h>
int main() {
printf("Enter a number");
fflush(stdout);
int a;
scanf("%d",&a);
for(int i=0;i<a;i++)
{
printf("%d",i);
}
fflush(stdout);
return 0;
}
請注意,它要求顯式刷新子進程的stdout,並將其寫入並配置為在調用方中不阻塞, 並顯式select()處理管道上的數據。 或者,您可以使用無緩沖管道(bufsize = 0)創建子進程,然后選擇()並逐字節讀取字節。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.