Thursday, April 28, 2011

Python's subprocess.Popen returns the same stdout even though it shouldn't

I'm having a very strange issue with Python's subprocess.Popen. I'm using it to call several times an external exe and keep the output in a list.

Every time you call this external exe, it will return a different string. However, if I call it several times using Popen, it will always return the SAME string. =:-O

It looks like Popen is returning always the same value from stdout, without recalling the exe. Maybe doing some sort of caching without actually calling again the exe.

This is my code:

def get_key():

    from subprocess import Popen, PIPE

    args = [C_KEY_MAKER, '/26', USER_NAME, ENCRYPTION_TEMPLATE, '0', ]
    process = Popen(args, stdout=PIPE)
    output = process.communicate()[0].strip()
    return output

if __name__ == '__main__':
    print get_key() # Returns a certain string
    print get_key() # Should return another string, but returns the same!

What on Earth am I doing wrong?!

From stackoverflow
  • Nothing. That works fine, on my own tests (aside from your indentation error at the bottom). The problem is either in your exe. or elsewhere.

    To clarify, I created a python program tfile.py

    cat > tfile.py
    #!/usr/bin/env python
    import random
    print random.random()
    

    And then altered tthe program to get rid of the indentation problem at the bottom, and to call tfile.py . It did give two different results.

    Fernando : I'm running on Windows, could that be the problem?
    Devin Jeanpierre : It's possible, but I doubt it. You could run such an example yourself and see if anything weird crops up, but that would be a serious bug in the subprocess module-- it should work identically in Linux and Windows, and it should work the way it does on my machine.
  • Your code is not executable as is so it's hard to help you out much. Consider fixing indentation and syntax and making it self-contained, so that we can give it a try.

    On Linux, it seems to work fine according to Devin Jeanpierre.

  • I don't know what is going wrong with your example, I cannot replicate this behaviour, however try a more by-the-book approach:

    def get_key():
    
        from subprocess import Popen, PIPE
    
        args = [C_KEY_MAKER, '/26', USER_NAME, ENCRYPTION_TEMPLATE, '0', ]
        output = Popen(args, stdout=PIPE).stdout
        data = output.read().strip()
        output.close()
        return data
    
  • It is possible (if C_KEY_MAKER's random behaviour is based on the current time in seconds, or similar) that when you run it twice on the command line, the time has changed in between runs and so you get a different output, but when python runs it, it runs it twice in such quick succession that the time hasn't changed and so it returns the same value twice in a row.

0 comments:

Post a Comment