Frage

Ich habe Befehl wie diese.

wmctrl -lp | awk '/gedit/ { print $1 }'

Und ich will seine Ausgabe in Python-Skript, ich diesen Code versucht,

>>> import subprocess
>>> proc =  subprocess.Popen(["wmctrl -lp", "|","awk '/gedit/ {print $1}"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> proc.stdout.readline()
'0x0160001b -1 6504   beer-laptop x-nautilus-desktop\n'
>>> proc.stdout.readline()
'0x0352f117  0 6963   beer-laptop How to get output from external command combine with Pipe - Stack Overflow - Chromium\n'
>>> proc.stdout.readline()
'0x01400003 -1 6503   beer-laptop Bottom Expanded Edge Panel\n'
>>> 

Es scheint mein Code falsch nur wmctrl -lp ist war auszuführen, und | awk '{print $1}' weggelassen erwarte, dass meine Ausgabe möchte 0x03800081

$ wmctrl -lp | awk '/gedit/ {print $1}'
0x03800081

Muss man bitte helfen.

War es hilfreich?

Lösung

Mit shell=True, sollten Sie eine einzelne Befehlszeile anstelle eines Arrays verwenden, sonst wird Ihre zusätzliche Argumente als Shell-Argumente interpretiert werden. Aus der subprocess Dokumentation :

  

Unter Unix mit shell = True: Wenn args ein String ist, es gibt die Befehlsfolge durch den Shell ausführen. Wenn args eine Sequenz ist, das erste Element gibt die Befehlsfolge und alle zusätzlichen Einzelteile werden als zusätzliche Schale Argumente behandelt werden.

So sollte Ihr Anruf sein:

subprocess.Popen("wmctrl -lp | sed /gedit/ '{print $1}'", shell=True, ...

Ich glaube, Sie auch eine unausgewogene Apostroph da drin haben.

Andere Tipps

Da Sie eine Sequenz in für das Programm vorbei, denkt es, dass das Rohr eine ist Argument wmcrtrl, wie wenn Sie getan haben

wmctrl -lp "|"

und damit das tatsächliche Rohr Betrieb verloren.

es einen einzelnen String machen sollte in der Tat geben Sie das richtige Ergebnis:

>>> import subprocess as s
>>> proc = s.Popen("echo hello | grep e", shell=True, stdout=s.PIPE, stderr=s.PIPE)
>>> proc.stdout.readline()
'hello\n'
>>> proc.stdout.readline()
''

Nach einigen Recherchen habe ich den folgenden Code, die für mich sehr gut funktioniert. Er druckt grundsätzlich sowohl stdout und stderr in Echtzeit. Hoffe, es hilft jemand anderes, der es braucht.

stdout_result = 1
stderr_result = 1


def stdout_thread(pipe):
    global stdout_result
    while True:
        out = pipe.stdout.read(1)
        stdout_result = pipe.poll()
        if out == '' and stdout_result is not None:
            break

        if out != '':
            sys.stdout.write(out)
            sys.stdout.flush()


def stderr_thread(pipe):
    global stderr_result
    while True:
        err = pipe.stderr.read(1)
        stderr_result = pipe.poll()
        if err == '' and stderr_result is not None:
            break

        if err != '':
            sys.stdout.write(err)
            sys.stdout.flush()


def exec_command(command, cwd=None):
    if cwd is not None:
        print '[' + ' '.join(command) + '] in ' + cwd
    else:
        print '[' + ' '.join(command) + ']'

    p = subprocess.Popen(
        command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd
    )

    out_thread = threading.Thread(name='stdout_thread', target=stdout_thread, args=(p,))
    err_thread = threading.Thread(name='stderr_thread', target=stderr_thread, args=(p,))

    err_thread.start()
    out_thread.start()

    out_thread.join()
    err_thread.join()

    return stdout_result + stderr_result

Wenn nötig, ich denke, es ist einfach, die Ausgabe oder Fehler in einer Zeichenfolge zu sammeln und zurück.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top