将bash脚本称为Python子进程--Bash陷入无限循环,导致输入错误

时间:2016-12-13 20:41:34

标签: python linux bash python-2.7 shell

我正在使用Python 2.7和Glade 3.15来创建一个GUI,允许按钮执行我的工作团队维护的各种现有bash / cshell脚本。我是Python的新手,但已经设法让基本的应用程序结构正常运行。但是,我正在调用的某些bash脚本将逐步执行多个用户提示并获取输入以确定最终行为。我遇到的问题是当我将bash脚本称为python子进程时,bash脚本似乎会反复进行空输入,从而导致提示无休止地循环。

例如: 一个bash脚本提示:

"Please enter your 4 digit document number:"
  ** accept user input in terminal **
"You entered ----, is that correct?
       1.) Yes
       2.) No " 

当从python调用时,终端将按下提示,发送空响应。由于bash脚本循环直到收到肯定响应,结果是终端无休止地打印:

"You entered ----, is that correct?
         1.) Yes
         2.) No "

我已经尝试过广泛地在这里和其他地方找到关于这个问题的答案,但还没有找到/开发出一个解决方案。

相对于这个问题,我的基本python如下(虽然我尝试了各种不同的方法)

import subprocess
from subprocess import Popen,PIPE
...
# Definition for subprocess calls
  def subprocess_cmd(self, command):
     process = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE)   
     process.wait()
     (output, err) = process.communicate()
     print output
...

# Script-Call Button
  def on_btnScript_clicked(self, object, data=None):
    self.subprocess_cmd("scriptname_is_here")

我只是想从我的python button_click事件中调用一个子进程来启动终端中的bash脚本,并等待键盘终端输入来遍历提示,就像它直接从终端运行一样。对不起这么久 - 想要彻底和明确。提前感谢您的帮助。

***** **** UPDATE

如果我使用.wait()方法从另一个独立的python文件调用子进程,则交互将按需运行。但是,当我通过GUI button_click事件调用子进程时,使用相同的参数和方法,发生循环异常。我认为这与我的mainDialog类中定义的按钮单击事件和subprocess_cmd'function'有关,但我不知道如何在保留与GUI的连接时将它们分开。

以下是我的代码的更多上下文

#!/usr/bin/python

# Library Imports
from gi.repository import Gtk
from os import system
import subprocess
from subprocess import Popen,PIPE
import time
try:
  import math
except:
   print "Math Library Missing"
   sys.exit(1)

class mainDialog:

# Build the 'form load' parameters
  def __init__(self):
    self.gladefile = "test.glade"
    self.builder = Gtk.Builder()
    self.builder.add_from_file(self.gladefile)
    self.builder.connect_signals(self)
    self.winMain = self.builder.get_object("winMain")
    self.winCptArg = self.builder.get_object("winCptArg")
    self.winMsbHelp = self.builder.get_object("winMsbHelp")
    self.winCptHelp = self.builder.get_object("winCptHelp")
    self.winAiHelp = self.builder.get_object("winAiHelp")
    self.winMain.move(2625, 400)
    self.winMain.show()

# Definition for subprocess calls
  def subprocess_cmd(self, command):
     process = subprocess.Popen(command)   
     process.wait()
...

# Script-Call Button
  def on_btnScript_clicked(self, object, data=None):
    self.subprocess_cmd("scriptname_is_here")

if __name__ == "__main__":
  main = mainDialog()
  Gtk.main()

2 个答案:

答案 0 :(得分:1)

只需使用os.system

from os import system
...
# Definition for subprocess calls
def subprocess_cmd(self, command):
    process = system(str(command))
...
# Script-Call Button
def on_btnScript_clicked(self, object, data=None):
    self.os.system("echo scriptname_is_here")

语法为os.system("executable option parameter") 例如,

os.system("ls -al /home")

答案 1 :(得分:0)

好吧,如果有人有兴趣,为了达到我想要的目的,我只是单独留下stdin和stdout,并将.wait()方法应用于子进程定义 - 但这仅在从独立python脚本调用时才有效;连接到GUI按钮单击事件时,我无法保留功能。

 def subprocess_cmd(self, command):
     process = subprocess.Popen(command).wait() 
...

 def on_btnScript_clicked(self, object, data=None):
    self.subprocess_cmd("filepath/scriptname_is_here")

stdin和stdout可以保留为默认值,只要子进程定义附加了wait()方法,就可以实现标准终端交互。