3

I'm having an issue with subprocess.Popen and what I believe to be pipes. I have the following block of code which works without issue 100% of the time when running from the cli:

    p = subprocess.Popen("psexec \\\\" + serverName.get() + " cmd /c \
        ver & \
        echo %USERDOMAIN% & \
        dir /a C:\pagefile.sys | find \"pagefile.sys\" & \
        dir C:\ | find \"bytes free\" & \
        dir D:\ | find \"bytes free\" ", \
        stdin=None, stdout=subprocess.PIPE, stderr=None)

    ### Assign the results from the Popen
    results = p.communicate()[0]
    rc = p.returncode

    print 'results: ' + str(results)
    sys.exit()

Output:

PsExec v1.90 - Execute processes remotely
Copyright (C) 2001-2007 Mark Russinovich
Sysinternals - www.sysinternals.com

The device is not ready.
cmd exited on XXXXXXX with error code 1.

Microsoft Windows XP [Version 5.1.2600]
PROD
02/23/2011  09:37 AM     1,610,612,736 pagefile.sys
              49 Dir(s)  17,104,437,248 bytes free

I had this program complete, but once I compiled it with py2exe, it would just hang or crash. I tracked that issue down to py2exe not liking undefined stdin, out, or err in subprocess. I then modified my code as follows:

    p = subprocess.Popen("psexec \\\\" + serverName.get() + " cmd /c \
        ver & \
        echo %USERDOMAIN% & \
        dir /a C:\pagefile.sys | find \"pagefile.sys\" & \
        dir C:\ | find \"bytes free\" & \
        dir D:\ | find \"bytes free\" ", \
        stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

    p.stdin.close()

    ### Assign the results from the Popen
    results = p.communicate()[0]
    rc = p.returncode

    print 'results: ' + str(results)
    sys.exit()

This code works 100% of the time as well, but when I print results, it only shows me the standard psexec messages, not the output of the commands executed.

Output:

results:
PsExec v1.90 - Execute processes remotely
Copyright (C) 2001-2007 Mark Russinovich
Sysinternals - www.sysinternals.com

cmd exited on XXXXXXX with error code 1.

I tried to combat this by adding shell=true to the subprocess options, but when I do that the program just hangs 99% of the time. It will actually run 1% of the time . I noticed that while the program is hanging, if I go into task manager and manually kill the psexec process, the desired output is shown. This is driving me crazy and I've been searching forever without finding anything. The code is running on WinXP python v2.7. Please let me know if you have any questions or need any additional information.

Hanging Code:

    p = subprocess.Popen("psexec \\\\" + serverName.get() + " cmd /c \
        ver & \
        echo %USERDOMAIN% & \
        dir /a C:\pagefile.sys | find \"pagefile.sys\" & \
        dir C:\ | find \"bytes free\" & \
        dir D:\ | find \"bytes free\" ", \
        stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)

    p.stdin.close()

    ### Assign the results from the Popen
    results = p.communicate()[0]
    rc = p.returncode

    print 'results:' + str(results)
    sys.exit()

Desired output after killing psexec.exe from task manager:

results:
PsExec v1.90 - Execute processes remotely
Copyright (C) 2001-2007 Mark Russinovich
Sysinternals - www.sysinternals.com


PROD
02/23/2011  09:37 AM     1,610,612,736 pagefile.sys
              49 Dir(s)  17,102,487,552 bytes free
The device is not ready.
Tony
  • 391
  • 1
  • 4
  • 11
  • You are trying to execute a series of commands on the remote machine using `&` in between each command. Now, if you do *not* use `shell=True` then all the commands are passed as arguments to `psexec` and executed on the remote machine. But if you *do* use `shell=True` the shell will execute each command individually, so `cmd /c ver` gets executed on the remote machine, but `echo %USERDOMAIN%` and the remaining commands are executed on the *local* machine! (Notice how the output of the `ver` command does not appear after you kill `psexec`) – srgerg Mar 07 '11 at 07:05
  • Also, when I tried to replicate your results the `psexec` command would hang when I set `stdin = subprocess.PIPE`. The value of `shell` did not seem to be related. – srgerg Mar 07 '11 at 07:06
  • It may be hanged by License prompt. Please see the link http://stackoverflow.com/questions/5151034/psexec-gets-stuck-on-licence-prompt-when-running-non-interactively – SHENGPING WANG May 10 '14 at 08:27
  • it is hand by license agreement. Please see the link: http://stackoverflow.com/questions/5151034/psexec-gets-stuck-on-licence-prompt-when-running-non-interactively – SHENGPING WANG May 10 '14 at 08:28

3 Answers3

0

[This should be a comment, but I don't have the rep to leave comments]

I've heard of a lot of problems with subprocess.PIPE. Try making stdin, stdout, and stderr all point to temporary files. Then you can use p.wait() instead of communicate(). Does that seem to work correctly?

Xepo
  • 616
  • 5
  • 7
0

try running the psexec with -i it works for me

p = subprocess.Popen("psexec " "-i "  . . . 
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0

I've seen this problem a once:

  1. Redirecting traffic to temporary files seems a working solution - the problem is the additional code needed to access the process output - but it is a stable solution. The problem is the additional code needed to get to the process output (if you want to display it while it is running - if not, it's just dumping a file)
  2. You could also check fabric's local implementations - I haven't run psexec with it, but all other processes worked fine (except for the fact it does not provide a timeout mechanism)
dahpgjgamgan
  • 2,977
  • 4
  • 25
  • 26