【问题标题】:Python Popen hanging with psexec - undesired resultsPython Popen 与 psexec 一起挂起 - 不希望的结果
【发布时间】:2011-07-08 20:37:24
【问题描述】:

我对 subprocess.Popen 以及我认为是管道的问题有疑问。我有以下代码块,从 cli 运行时 100% 的时间都没有问题:

    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()

输出:

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

我已经完成了这个程序,但是一旦我用 py2exe 编译它,它就会挂起或崩溃。我将此问题追溯到 py2exe 不喜欢子进程中未定义的标准输入、输出或错误。然后我修改了我的代码如下:

    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()

这段代码也可以 100% 工作,但是当我打印结果时,它只显示标准 psexec 消息,而不是执行命令的输出。

输出:

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.

我试图通过在子进程选项中添加 shell=true 来解决这个问题,但是当我这样做时,程序只会挂起 99% 的时间。它实际上会运行 1% 的时间。我注意到,当程序挂起时,如果我进入任务管理器并手动终止 psexec 进程,则会显示所需的输出。这让我发疯,我一直在寻找,但没有找到任何东西。该代码在 WinXP python v2.7 上运行。如果您有任何问题或需要任何其他信息,请告诉我。

挂码:

    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()

从任务管理器中杀死 psexec.exe 后所需的输出:

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.

【问题讨论】:

  • 您正尝试在远程机器上执行一系列命令,在每个命令之间使用&。现在,如果您使用shell=True,那么所有命令都作为参数传递给psexec,并在远程机器上执行。但是如果你 使用shell=True,shell 将单独执行每个命令,所以cmd /c ver 在远程机器上执行,但echo %USERDOMAIN% 和其余命令在本地执行 机器! (注意杀死psexecver 命令的输出不会出现)
  • 另外,当我尝试复制您的结果时,psexec 命令会在我设置stdin = subprocess.PIPE 时挂起。 shell 的值似乎不相关。
  • 可能会被License提示挂起。请看链接stackoverflow.com/questions/5151034/…
  • 它是由许可协议提供的。请看链接:stackoverflow.com/questions/5151034/…

标签: python subprocess pipe py2exe psexec


【解决方案1】:

[这应该是评论,但我没有代表离开 cmets]

我听说 subprocess.PIPE 存在很多问题。尝试使标准输入、标准输出和标准错误都指向临时文件。然后你可以使用 p.wait() 而不是communicate()。这似乎工作正常吗?

【讨论】:

    【解决方案2】:

    我曾经见过这个问题:

    1. 将流量重定向到临时文件似乎是一个可行的解决方案 - 问题是访问进程输出所需的额外代码 - 但它是一个稳定的解决方案。问题是获取进程输出所需的额外代码(如果你想在它运行时显示它 - 如果不是,它只是转储一个文件)
    2. 您还可以检查 fabric's local 实现 - 我没有使用它运行 psexec,但所有其他进程都运行良好(除了它不提供超时机制这一事实)

    【讨论】:

      【解决方案3】:

      尝试使用 -i 运行 psexec 它对我有用

      p = subprocess.Popen("psexec " "-i "  . . . 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-04
        • 2020-12-02
        • 1970-01-01
        • 2023-03-06
        • 2015-08-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多