2013-01-10 70 views
1

如何调用以bash脚本编写的外部程序,以便该脚本生成的输出在sys.stdout中可用,以便我可以记录通过python输出到一个文件中。通过Python调用外部程序并将输出传递给标准输出

例如。我现在请他们通过下面的代码片段

if os.name == 'nt': 
    path = module_dir_run+'/run.bat' 
else: 
    path = module_dir_run+'/run.sh' 
if os.path.isfile(path): 
    if (splitargs.arg): 
     try: 
      call([path, splitargs.arg]) 
     except: 
      pass 
    else: 
     try: 
      call([path]) 
     except: 
      pass 
else: 
    print "Not found : " + path 

当我存储sys.stdout = file(filename, "w") IT卖场无论该蟒蛇输出值,但不是什么脚本输出。

注意:我试图运行的脚本是一个交互式脚本,所以在调用结束后,控件已经回到python,我如何获得所有写在终端中的内容? 有什么建议吗?

+0

是否必须写输出到'stdout'?我建议只写入一个文件然后读取文件。 – Skyler

+0

你需要包含'call'是什么。 –

+0

@InbarRose:'subprocess.call'据推测。 –

回答

1

我总是使用subprocess.Popen()从一个Python脚本内运行另一个程序变量e.g。例如:

import subprocess 

print "Starting process..." 
process = subprocess.Popen(["echo", "a"], shell=False) 
process.wait() 
print "Done" 

可以处理的输出重定向到另一个这样的文件:

import subprocess 

print "Starting process..." 
with open("./out.log", "w") as f: 
    process = subprocess.Popen(["echo", "a"], shell=False, stdout=f) 
    process.wait() 
print "Done" 

重定向标准错误,也可以通过“标准错误”参数。

当你重定向到写自己的文件当前的脚本有sys.stdout,你可以做到这一点,以重定向在你的子太:

import subprocess 
import sys 

sys.stdout = open("./out.log", "w") 
print "Starting process..." 
sys.stdout.flush() 
process = subprocess.Popen(["echo", "a"], shell=False, stdout=sys.stdout) 
process.wait() 
print "Done" 
+0

该脚本具有交互功能,用户必须进行交互,这些脚本是否也会被记录下来?如果我将stdout传递给文件描述符,用户将无法与脚本交互! –

+0

因此,您希望子流程的输出在控制台上都可见并写入日志文件?至于交互,当前stdin是隐式传递的,用户将能够从键盘输入命令。 – ZalewaPL

+0

是的,这就是我想要的!但我希望用户与脚本本地交互,并且当脚本结束时,变量或stdout可以存储它在终端中写入的任何内容。 –

0

正如Martijn Pieters所述,您必须为您的call()呼叫提供替代stdout

基本上有2种方式: *要么提供一个已打开的文件(如您已更改sys.stdout,这可能会被罚款) *使用stdout=subprocess.PIPE和阅读并自己处理stdout。 (不是通过subprocess.call()话,而是通过由subprocess.Popen()返回的对象。)

请注意,更改sys.stdout不会真正改变你的进程的stdout从操作系统的角度出发,而是将你的程序顺序输出都在非 - 实际文件描述符。

1

你可以写这样的调用的输出到使用:

variable = subprocess.Popen(
    ['ls', 'mydir/'], # note that the command is split on whitespace 
    stdout=subprocess.PIPE).communicate()[0] 
+0

我试图运行的脚本具有交互功能,用户必须键入他们的名字等,这些脚本也会被记录下来吗? –

+0

@SunnyRockzzs,所以你想使它可以像''script.py arg1 arg2''那样调用?如果我理解正确,也许这[堆栈溢出问题](http://stackoverflow.com/questions/4429966/how-to-make-a-python-script-pipeable-in-bash)将带你进一步 –

+0

我认为他的意思是他正试图运行的脚本从stdin读入。请注意他使用“互动”一词。所以需要将stdin重定向回运行python脚本的shell。 –

0

这可能是有用的。特别是因为大多数其他答案不明白你需要将父shell的stdin重定向到子进程的stdin,因为你调用的程序/脚本是“交互式”的。

Python and subprocess input piping

相关问题