7

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.)

6 Answers 6

11

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
Sign up to request clarification or add additional context in comments.

Comments

4

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.

1 Comment

Here is the file. It uses the optparse module, so there is no sys.argv[].
0

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.

Comments

0

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 ;-)

Comments

0

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.

1 Comment

That site looks kind of dead, I think it might be a more fruitful idea to go to their Gitorious project, implement the change in a branch, and request that it be incorporated into the project.
0

In bash, you can also use process substitution:

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

For a single input /dev/stdin works, but process substitution also applies for several inputs (and even outputs)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.