2010-07-17 2 views
7

Ein Python-Skript Ich betreiben müssen nimmt die Eingabe nur aus einer Datei als Befehlszeilenargument übergibt, etwa so:einen Python-Skript erzwingen Eingang nehmen von STDIN

$ markdown.py input_file 

Gibt es eine Möglichkeit, es zu erhalten, Akzeptieren Sie stattdessen die Eingabe von STDIN? Ich möchte in der Lage, dies durch Bash zu tun, ohne signifikant die Python-Skript zu ändern:

$ echo "Some text here" | markdown.py 

Wenn ich das Python-Skript zu ändern haben, wie würde ich vorgehen?

(EDIT: Here ist das Skript, das die Befehlszeilenoptionen wird das Parsen.)

Antwort

11

Ich bin nicht sicher, wie portable es ist, aber auf Unix-y-Systemen können Sie /dev/stdin als Dateiname:

$ echo -n hi there | wc /dev/stdin 
     0  2  8 /dev/stdin 
+0

Danke! Genau das habe ich gesucht. – Karthik

4

Stellen Sie sicher, das in der Nähe der Anfang der Datei ist:

import sys 

Dann suchen Sie nach etwas wie folgt aus:

filename = sys.argv[1] 
f = open(filename) 

und es mit diesem ersetzen:

f = sys.stdin 

Es ist schwierig, genauer zu sein, ohne das Skript zu sehen, mit dem Sie beginnen.

+0

[hier] (http://codaset.com/repo/python-markdown/source/master/blob/067d88bc41c7924c9087b724ff5247235243ce6b/markdown/commandline.py) ist die Datei. Es verwendet das optparse-Modul, daher gibt es keine sys.argv []. – Karthik

0

Im Code, den Sie haben eine Zeile wie diese:

if not len(args) == 1: 

Was Sie tun könnten, ist zu überprüfen, ob Sie keinen Dateinamen haben und stattdessen entweder "/ dev/stdin" (auf einem System, das es erlaubt) verwenden.

eine andere Lösung ersetzen, nur:

if not len(args) == 1: 
    parser.print_help() 
    return None, None 
else: 
    input_file = args[0] 

mit

if not len(args) == 1: 
    input_file = sys.stdin 
else: 
    input_file = open(args[0]) 

Das bedeutet natürlich, dass die zurückgegebene „input_file“ ist nicht länger ein Name Datei, sondern ein Dateiobjekt, das weiter Mittel Änderungen in der aufrufenden Funktion.

Erste Lösung ist weniger Modifikationen, aber mehr Plattform-spezifische, zweite ist mehr Arbeit, sollte aber auf mehr Systemen arbeiten.

0

Ich rate von den Details Ihrer Frage, die Sie über Python-Markdown stellen, also habe ich die entsprechende Zeile im Quellcode für Sie aufgespürt: Daniels Weg zu tun, in Zeile 443 von markdown/__init__.py, Sie würden

input_file = codecs.open(input, mode="r", encoding=encoding) 

mit

input_file = codecs.EncodedFile(sys.stdin, encoding) 

Obwohl dann würden Sie nicht in der Lage sein, tatsächlich Dateien verarbeiten danach, so dass für einen allgemein nützlichen Hack ersetzen mögen, können Sie in einem bedingten setzen könnten:

if input: 
    input_file = codecs.open(input, mode="r", encoding=encoding) 
else: 
    input_file = codecs.EncodedFile(sys.stdin, encoding) 

und dann müssten Sie markdown/commandline.py anpassen, um nicht zu beenden, wenn es einen Dateinamen nicht gegeben: Wechsellinien 72-73

parser.print_help() 
return None, None 

zu

input_file = None 

Der Punkt ist, Es ist nicht wirklich eine einfache Sache zu tun. An dieser Stelle wollte ich mit einer speziellen Datei vorschlagen wie Mark Rushakoff tat, wenn er mich nicht geschlagen hatte, um es

0

;-) Ich schlage vor, gehen hier:

http://codaset.com/repo/python-markdown/tickets/new

Und eine Vorlage Ticket fordert sie auf, das Feature hinzuzufügen. Es sollte für sie einfach sein und sie könnten bereit sein, weiterzumachen.

+0

Diese Seite sieht irgendwie tot aus, ich denke, es könnte eine fruchtbarere Idee sein, zu ihrem [Gitorious-Projekt] (http://gitorious.org/python-markdown) zu gehen, die Änderung in einer Verzweigung zu implementieren und sie anzufordern in das Projekt integriert werden. –

0

In bash können Sie auch process substitution verwenden:

markdown.py <(echo "Some text here") 

für einen einzelnen Eingang/dev/stdin funktioniert, aber Prozess Substitution gilt auch für mehrere Eingänge (und sogar Ausgänge)