3

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 でコンパイルすると、ハングまたはクラッシュするだけでした。サブプロセスで未定義のstdin、out、またはerrを好まない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.
4

3 に答える 3

0

-iを指定してpsexecを実行してみてください。

p = subprocess.Popen("psexec " "-i "  . . . 
于 2011-03-09T10:12:28.117 に答える
0

私はこの問題を一度見ました:

  1. トラフィックを一時ファイルにリダイレクトすることは有効な解決策のようです。問題は、プロセスの出力にアクセスするために必要な追加のコードです。しかし、これは安定した解決策です。問題は、プロセス出力に到達するために必要な追加のコードです (実行中に表示したい場合 - そうでない場合は、ファイルをダンプするだけです)。
  2. また、ファブリックのローカル実装を確認することもできます- 私はそれで psexec を実行していませんが、他のすべてのプロセスは正常に動作しました (タイムアウト メカニズムを提供しないという事実を除いて)。
于 2011-09-06T19:15:49.223 に答える
0

[これはコメントのはずですが、コメントを残す担当者がいません]

subprocess.PIPE に関する多くの問題について聞いたことがあります。stdin、stdout、stderr のすべてが一時ファイルを指すようにしてみてください。次に、communication() の代わりに p.wait() を使用できます。それは正しく機能しているように見えますか?

于 2011-03-07T03:37:03.037 に答える