3

以前、私はこの質問をしました:

ネイティブ python を使用して ping または traceroute を実行するにはどうすればよいですか?

ただし、python はルートとして実行されていないため、ネイティブ python で ping/traceroute を実行するために必要な未加工の ICMP ソケットを開く機能がありません。

これにより、システムの ping/traceroute シェル コマンドの使用に戻ります。この質問には、subprocessうまく機能しているように見えるモジュールを使用した例がいくつかあります。

Python でサイトに ping を実行しますか?

ただし、もう 1 つ要件があります。生成された出力にアクセスできる必要があります (たとえば、長時間実行される traceroute の場合など)。

上記のすべての例はシェル コマンドを実行し、コマンドが完了すると完全な出力にアクセスできるようになります。生成されたコマンド出力にアクセスする方法はありますか?

編集: Alex Martelliの答えに基づいて、これがうまくいきました:

import pexpect

child = pexpect.spawn('ping -c 5 www.google.com')

while 1:
        line = child.readline()
        if not line: break
        print line,
4

4 に答える 4

6

pexpectは、あなたのような要件に対して「デフォルトで」到達するものです。他にも同様のモジュールがありますが、ほとんどの場合、pexpect は最もリッチで、最も安定しており、最も成熟したモジュールです。わざわざ代替案を探したいのは、Windows でも正しく実行する必要がある場合です (ping と traceroute にはそれぞれ問題がある可能性があります)。その場合はお知らせください。アレンジできるものを見てください!-)

于 2009-07-20T06:05:33.053 に答える
5

subprocessモジュールのドキュメントを読む必要があります。外部プロセスを実行し、その出力にリアルタイムでアクセスする方法が説明されています。

基本的に、あなたはそうします

from subprocess import Popen, PIPE
p = Popen(['tracert', host], stdout=PIPE)
while True:
    line = p.stdout.readline()
    if not line:
        break
    # Do stuff with line

実際、リンク先の SO の質問の回答は、必要なものに非常に近いものです。Corey Goldberg の回答では、パイプと を使用しreadlineていますが、ping を使用して実行-n 1されるため、違いを生むほど長くは続きません。

于 2009-07-20T06:08:39.193 に答える
1

サブプロセス用の tty ペアを作成し、その中で実行できます。C標準(C99 7.19.3)によると、stdoutがラインバッファリングされるのは(完全にバッファリングされたくないと言うのとは対照的に)、それが端末のときだけです。(または明らかに setvbuf() と呼ばれる子)。

os.openpty() をチェックしてください。

テストされていないコード:

master, slave = os.openpty()
pid = os.fork()
if pid == 0:
    os.close(master)
    os.dup2(slave, 0)
    os.dup2(slave, 1)
    os.dup2(slave, 2)
    os.execv("/usr/sbin/traceroute", ("traceroute","4.2.2.1"))
    # FIXME: log error somewhere
    os.exit(1)
os.close(slave)
while True:
    d = os.read(master)
    if len(d) == 0:
        break
    print d
os.waitpid(pid, 0)

setvbuf() は libc 関数であり、syscall ではないため、( fork() の直後に) 子プロセスで setvbuf() を呼び出しても機能しないことに注意してください。現在のプロセス出力の状態を変更するだけで、新しいバイナリがロードされたときに exec 呼び出しで上書きされます。

于 2009-07-20T06:32:52.483 に答える