1

Hello i am using the subprocess.Popen() class and i succesful execute commands on the terminal, but when i try to execute programs for example an script written on Python and i try to pass arguments the system fails.

This is the code:

            argPath = "test1"
            args = open(argPath, 'w')

            if self.extract.getByAttr(self.block, 'name', 'args') != None:
                args.write("<request>"+self.extract.getByAttr(self.block, 'name', 'args')[0].toxml()+"</request>")
            else:
                args.write('')

            car = Popen(shlex.split('python3.1 /home/hidura/webapps/karinapp/Suite/ForeingCode/saveCSS.py', stdin=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE))
            args.close()

            dataOut = car.stdout.read().decode()
            log = car.stderr.read().decode()


            if dataOut!='':
                return dataOut.split('\n')

            elif log != '':
                return log.split('\n')[0]

            else:
                return None

And the code from the saveCSS.py

from xml.dom.minidom import parseString
import os
import sys

class savCSS:
        """This class has to save

    the changes on the css file.
    """

    def __init__(self, args):

        document = parseString(args)
        request = document.firstChild

        address = request.getElementsByTagName('element')[0]
        newdata = request.getElementsByTagName('element')[1]

        cssfl = open("/webapps/karinapp/Suite/"+address.getAttribute('value'), 'r')
        cssData = cssfl.read()
        cssfl.close()

        dataCSS = ''
        for child in newdata.childNodes:
            if child.nodeType == 3:
                dataCSS += child.nodeValue

        nwcssDict = {}

        for piece in dataCSS.split('}'):
            nwcssDict[piece.split('{')[0]] = piece.split('{')[1]


        cssDict = {}

        for piece in cssData.split('}'):
            cssDict[piece.split('{')[0]] = piece.split('{')[1]


        for key in nwcssDict:
            if key in cssDict == True:
                del cssDict[key]

            cssDict[key] = nwcssDict[key]


        result = ''
        for key in cssDict:
            result += key+"{"+cssDict[key]+"}"


        cssfl = open(cssfl.name, 'a')
            cssfl.write(result)
            cssfl.close()



if __name__ == "__main__":
    savCSS(sys.stdin)

BTW: There's no output...

Thanks in advance.

1
  • 1
    Obviously you know how to use Subprocess, what's the specific error? Commented Jan 26, 2011 at 6:07

2 Answers 2

3

OK, I'm ignoring that your code doesn't run (neither the script you try to execute, not the main script actually works), and looking at what you are doing:

It does execute the script, or you would get an error, like "bin/sh: foo: not found".

Also you seem to be using an open file as stdin after you have written to it. That doesn't work.

>>> thefile = open('/tmp/foo.txt', 'w')
>>> thefile.write("Hej!")
4
>>> thefile.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IOError: not readable

You need to close the file, and reopen it as a read file. Although better in this case would be to use StringIO, I think.

To talk to the subprocess, you use communicate(), not read() on the pipes.

I'm not sure why you are using shell=True here, it doesn't seem necessary, I would remove it if I was you, it only complicates stuff unless you actually need the shell to do things. Specifically you should not split the command into a list when using shell=True. What your code is actually doing, is starting a Python prompt.

Sign up to request clarification or add additional context in comments.

2 Comments

The code of the file saveCSS.py is working the other is an extract of he area that is making the call of the function. And the mayor problem is when i pass the arguments to the saveCSS.py that the system doesn't execute the code and when execute the code doesn't pass the arguments.
@hidura: No, the saveCSS.py code is not working, not even in your updated form. Firstly there is a lot of indentation errors, and once I fix that, it says "TypeError: Parse() argument 1 must be string or read-only buffer, not file". In any case, I explained above why. I repeat: Do NOT pass in shell=True. Also, there are a lot of other errors, which I also explained above.
2

You should rather use communicate() instead of .stdout.read().

And the code you posted isn't even correct:

Popen(shlex.split('python3.1 /home/hidura/webapps/karinapp/Suite/ForeingCode/saveCSS.py', stdin=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)

There's a missing parenthesis, and from the stdout/stderr parameters, it's clear that you get no output to the console, but rather into pipes (if that's what you meant by "There's no output...").

Your code will actually work on Windows, but on Linux you must remove the shell=True parameter. You should always omit that parameter if you provide the full command line yourself (as a sequence).

4 Comments

In the copy i miss that parenthesis and on Linux is not working without the shell=True
@hidura: Then check .returncode of the Popen object after you called communicate(). Should be zero if your other Python script is successful.
He is giving me a code 1 theres a mistake but the stderr giving me this: [Wed Jan 26 10:43:19 2011] [error] [client 127.0.0.1] log = car.stderr.read().decode(), referer: dev.karinapp.com [Wed Jan 26 10:43:19 2011] [error] [client 127.0.0.1] ValueError: read of closed file, referer: dev.karinapp.com
@hidura: I explicitly told you to use a single call to communicate() instead of reading the file-like stdout/stderr.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.