#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Posts
    4
    Rep Power
    0

    Python run a Shell Script


    Hello

    I need run a shell script and return the output to QT textedit.

    command is this type:
    ./script.sh -m c2,c3,c4,c5 ./folder/


    Code:
    self.process = subprocess.Popen(comando, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
     
    while(self.process.poll() != 0): 	
    self.textEdit_saida_consola.setText(self.process.communicate()[0])
    This code don't work and it don't execute the script. Doesn't appear any error.

    if the command is 'ls' works well.

    Thanks in advance
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480

    More detail required.


    Please show a complete program that works using
    comando = 'ls'

    for instance,
    Code:
    import subprocess
    
    comando = 'ls'
    
    process = subprocess.Popen(comando, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
     
    while process.poll():
        print(process.communicate()[0]())
    "works" but doesn't show any output.
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2009
    Posts
    479
    Rep Power
    33
    You probably want check_output or work with pipes/popen directly. See Doug Hellmann's Python Module of the Week for more info. Note that you may not get any output until the called program has finished.
    Code:
    import subprocess
    output = subprocess.check_output(['ls', '-1'])
    print output
    Last edited by dwblas; September 26th, 2013 at 09:57 PM.
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Posts
    4
    Rep Power
    0
    dwblas:
    I need it to work in real time.

    b49P23TIvg:
    The whole code is too large, this is the only part revelante.
    Using the print does not work, but using self.textEdit_saida_consola.setText appears in the text window Qt

    Now I try this, but doesn't work again, it blocks the Qt window:
    Code:
    self.process = subprocess.Popen('ls', close_fds=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
    
    fcntl.fcntl(self.process.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)	  	
    while True: 		
            myoutputtext = '' 		
            try: 			
                       myoutputtext = self.process.stdout.read() 		
            except IOError: 			
                      pass 		
            self.textEdit_saida_consola.setText(myoutputtext)
    with the initial code did the following test:
    Code:
    self.process = subprocess.Popen('./teste.sh', close_fds=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    while(self.process.poll() != 0): #É igual a 0 quando o processo acabar
    	self.textEdit_saida_consola.setText(self.process.communicate()[0])
    the ./test.sh:
    Code:
    echo "test" 
    sleep 2 
    echo "test" 
    sleep 10
    Appears in qt window when finish.

    Do you have more any idea?

    Thanks for the help
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2009
    Posts
    479
    Rep Power
    33
    Have you tried popen3 or a sys.stdout.flush() in the program? Will try to come up with an example later and am hoping that it doesn't include threads/multiprocessing.

    Edit: this works for me (from the Python Module of the Week link) but is it the same as what you are trying to do.
    Code:
    ##test1A.py
    import time
    import sys
    
    for j in range(10):
        print j              ## print adds a newline
        sys.stdout.flush()  ## flush the output so it can be read
        time.sleep(1)
    Code:
    ##  2nd program
    import subprocess
    
    proc = subprocess.Popen(['python','./test1A.py'],stdout=subprocess.PIPE)
    while True:
      line = proc.stdout.readline()
      if line:
        print "test:", line.strip()
      else:
        break
    
    """ prints
    test: 0
    test: 1
    test: 2
    test: 3
    test: 4
    test: 5
    test: 6
    test: 7
    test: 8
    test: 9
    """
    Last edited by dwblas; September 27th, 2013 at 01:22 PM.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2013
    Posts
    13
    Rep Power
    0
    Code:
    import getpass
    import os
    userz = getpass.getuser()
    # add the directory which contains that script
    os.chdir("/home/" + userz + "/Desktop/")
    params = ['./script.sh', '-m', 'c2,c3,c4,c5', './folder/']
    subprocess.check_call(params)
    You can open up a terminal window and see that output if you add this in front of ./script.sh:
    Code:
    'xfce4-terminal', '-H', '-x'
    Personally I use it to telnet into my router, cause I am too lazy to open up a terminal window and type everything manually.
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Posts
    4
    Rep Power
    0
    Originally Posted by dwblas
    Have you tried popen3 or a sys.stdout.flush() in the program? Will try to come up with an example later and am hoping that it doesn't include threads/multiprocessing.

    Edit: this works for me (from the Python Module of the Week link) but is it the same as what you are trying to do.
    Code:
    ##test1A.py
    import time
    import sys
    
    for j in range(10):
        print j              ## print adds a newline
        sys.stdout.flush()  ## flush the output so it can be read
        time.sleep(1)
    Code:
    ##  2nd program
    import subprocess
    
    proc = subprocess.Popen(['python','./test1A.py'],stdout=subprocess.PIPE)
    while True:
      line = proc.stdout.readline()
      if line:
        print "test:", line.strip()
      else:
        break
    
    """ prints
    test: 0
    test: 1
    test: 2
    test: 3
    test: 4
    test: 5
    test: 6
    test: 7
    test: 8
    test: 9
    """
    Work well in console, but in graphic interface Qt I have same problem, appears only the last line after finishing the script.

    And I have other problem, interface to stop responding when it is running, I need to be able to press a button to kill the task when needed.

    How I use threads to resolve this problem?

    PuTTy: Your solution blocks the python program?
    I am interested that the output appears in the graphical interface.

    Thanks
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    May 2009
    Posts
    479
    Rep Power
    33
    Work well in console, but in graphic interface Qt I have same problem, appears only the last line after finishing the script.
    Which says the problem is in your Qt program. You did not say if you were sending a newline after each group of data and doing a sys.stdout.flush(). The quote above tells us nothing. What do you expect? That we spend all of our time comimg up with solution after solution until you find something you like. Come up with a simple example that we can use for more help.
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2013
    Posts
    4
    Rep Power
    0

    Arrow


    Originally Posted by dwblas
    Which says the problem is in your Qt program. You did not say if you were sending a newline after each group of data and doing a sys.stdout.flush(). The quote above tells us nothing. What do you expect? That we spend all of our time comimg up with solution after solution until you find something you like. Come up with a simple example that we can use for more help.
    Sorry, That script I use for example and work with print is
    the ./test.sh:
    Code:
    Code:
     echo "test"  
    sleep 2  
    echo "test"  
    sleep 10
    I can't change the script ".sh", I have to find a solution only by changing the code python, the code in script .sh call the ecasound program.

    I made this simple code will replicate the problem:
    Code:
    # -*- coding: utf-8 -*-
    
    from PyQt4 import QtCore, QtGui
    import subprocess
    
    try:
        _fromUtf8 = QtCore.QString.fromUtf8
    except AttributeError:
        _fromUtf8 = lambda s: s
    
    class Ui_MainWindow(object):
        process=None
    
        def setupUi(self, MainWindow):
            MainWindow.setObjectName(_fromUtf8("MainWindow"))
            MainWindow.resize(800, 600)
            self.centralwidget = QtGui.QWidget(MainWindow)
            self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
            self.pushButton = QtGui.QPushButton(self.centralwidget)
            self.pushButton.setGeometry(QtCore.QRect(250, 380, 301, 111))
            self.pushButton.setObjectName(_fromUtf8("pushButton"))
    	self.pushButton.setCheckable(True)
            self.textEdit = QtGui.QTextEdit(self.centralwidget)
            self.textEdit.setGeometry(QtCore.QRect(110, 50, 581, 311))
            self.textEdit.setReadOnly(True)
            self.textEdit.setObjectName(_fromUtf8("textEdit"))
            MainWindow.setCentralWidget(self.centralwidget)
            self.menubar = QtGui.QMenuBar(MainWindow)
            self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 25))
            self.menubar.setObjectName(_fromUtf8("menubar"))
            MainWindow.setMenuBar(self.menubar)
            self.statusbar = QtGui.QStatusBar(MainWindow)
            self.statusbar.setObjectName(_fromUtf8("statusbar"))
            MainWindow.setStatusBar(self.statusbar)
    
            self.retranslateUi(MainWindow)
            QtCore.QMetaObject.connectSlotsByName(MainWindow)
    
        def retranslateUi(self, MainWindow):
            MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
            self.pushButton.setText(QtGui.QApplication.translate("MainWindow", "REC", None, QtGui.QApplication.UnicodeUTF8))
    
        def start(self):#verifica se há erros e procede ao arranque, se der erros, aparece a mensagem e desactiva o botão gravar.
    	if self.pushButton.isChecked(): # a tecla gravar foi activada
    		self.pushButton.setText("STOP")
    		self.execute()
    		#vai retomar o botão ao estado normal:
    		self.pushButton.setText("REC")
    		self.pushButton.setChecked(False)
    		return True
    	else: # a tecla gravar foi desactivada
    		self.pushButton.setText("REC")		
    		self.stop()
    	return False
    
        def execute(self):
    	
    	#executar o comando
    	self.process = subprocess.Popen('./teste.sh', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    
    	#total=''
    	while True:
    		line=self.process.stdout.readline()
    		if line:
    			#total=total+line			
    			#self.textEdit.setText(total.strip())
    			print line.strip()
    		else:
    			break
    
    	return
    
    
        def stop(self):
            #comando para encerrar processo
    	print "exit"
    	self.process.kill()
    	return
    
    if __name__ == "__main__":
        import sys
        app = QtGui.QApplication(sys.argv)
        MainWindow = QtGui.QMainWindow()
        ui = Ui_MainWindow()
        ui.setupUi(MainWindow)
        QtCore.QObject.connect(ui.pushButton, QtCore.SIGNAL('clicked()'), ui.start)
        MainWindow.show()
        sys.exit(app.exec_())
    If doesn't work well because the indentation I have the code here:
    http://pastebin.com/0Ui4LiKg

    My English is poor, which makes it difficult to communicate.

    Sorry for everything
    Thanks for your patience.

IMN logo majestic logo threadwatch logo seochat tools logo