tags:

views:

104

answers:

5

A python script I need to run takes input only from a file passed as a command line argument, like so:

$ markdown.py input_file

Is there any way to get it to accept input from STDIN instead? I want to be able to do this through Bash, without significantly modifying the python script:

$ echo "Some text here" | markdown.py

If I have to modify the Python script, how would I go about it?

(EDIT: Here is the script that is parsing the command line options.)

+2  A: 

Make sure this is near the top of the file:

import sys

Then look for something like this:

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

and replace it with this:

f = sys.stdin

It's hard to be more specific without seeing the script that you're starting with.

Daniel Stutzbach
[Here](http://codaset.com/repo/python-markdown/source/master/blob/067d88bc41c7924c9087b724ff5247235243ce6b/markdown/commandline.py) is the file. It uses the optparse module, so there is no sys.argv[].
Karthik
+6  A: 

I'm not sure how portable it is, but on Unix-y systems you can name /dev/stdin as your file:

$ echo -n hi there | wc /dev/stdin
       0       2       8 /dev/stdin
Mark Rushakoff
Thank you! this is exactly what I was looking for.
Karthik
A: 

In the code you have a line like this:

if not len(args) == 1:

What you could do there is to check if you don't have a filename and instead either use "/dev/stdin" (on a system that allows it).

Another solution is to just replace:

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

with

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

That means of course that the returned "input_file" is no longer a file name but a file object, which means further modifications in the calling function.

First solution is less modifications but more platform specific, second is more work, but should work on more systems.

Mattias Nilsson
A: 

I'm guessing from the details of your question that you're asking about Python-Markdown, so I tracked down the relevant line in the source code for you: to do it Daniel's way, in line 443 of markdown/__init__.py, you'd want to replace

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

with

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

Although then you wouldn't be able to actually process files afterwards, so for a more generally useful hack, you could put in a conditional:

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

and then you'd have to adjust markdown/commandline.py to not quit if it isn't given a filename: change lines 72-73

parser.print_help()
return None, None

to

input_file = None

The point is, it's not really a simple thing to do. At this point I was going to suggest using a special file like Mark Rushakoff did, if he hadn't beaten me to it ;-)

David Zaslavsky
A: 

I suggest going here:

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

And submitting a ticket requesting them to add the feature. It should be straightforward for them and so they might be willing to go ahead and do it.

Winston Ewert
That site looks kind of dead, I think it might be a more fruitful idea to go to their [Gitorious project](http://gitorious.org/python-markdown), implement the change in a branch, and request that it be incorporated into the project.
David Zaslavsky