Python Popen 与 psexec 挂起 - 不良结果

发布于 2024-10-20 04:49:39 字数 3005 浏览 7 评论 0原文

我对 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 不喜欢子进程中未定义的 stdin、out 或 err。然后我修改了我的代码,如下所示:

    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.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一袭水袖舞倾城 2024-10-27 04:49:39

[这应该是一条评论,但我没有代表留下评论]

我听说 subprocess.PIPE 有很多问题。尝试使 stdin、stdout 和 stderr 全部指向临时文件。然后你可以使用p.wait()而不是communicate()。这看起来工作正常吗?

[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?

梦行七里 2024-10-27 04:49:39

我曾经见过这个问题:

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

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)
情泪▽动烟 2024-10-27 04:49:39

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

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

try running the psexec with -i
it works for me

p = subprocess.Popen("psexec " "-i "  . . . 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文