A few arguments with stdin in Python

I have a burning question regarding passing a few stdin arguments when running a Python script from a Unix terminal. Consider the following command:

$ cat file.txt | python3.1 pythonfile.py 

Then the contents of file.txt (accessible via the "cat" command) will be passed to the python script as standard input. This works great (although a more elegant way would be nice). But now I have to pass another argument, which is just a word to be used as a query (and then two words). But I canโ€™t figure out how to do this properly, as the cat-pipe will give errors. And you cannot use standard input() in Python because it will result in an EOF error (you cannot combine stdin and input() in Python).

+7
python pipe stdin eof variadic-functions
source share
4 answers

While Steve Barnes answer will work, this is not the most โ€œpythonicโ€ way of doing things. A more elegant way is to use sys arguments and open and read the file in the script itself. Thus, you do not need to trace the output of the file and figure out a workaround, you can just pass the file name as another parameter.

Something like (in a python script):

 import sys with open(sys.argv[1].strip) as f: file_contents = f.readlines() # Do basic transformations on file contents here transformed_file_contents = format(file_contents) # Do the rest of your actions outside the with block, # this will allow the file to close and is the idiomatic # way to do this in python 

So (on the command line):

 python3.1 pythonfile.py file.txt postarg1 postarg2 
-one
source share

I am sure the stdin marker with the trick:

 cat file.txt | python3.1 prearg - postarg 

A more elegant way is probably to pass file.txt as an argument, then open and read it.

+5
source share

The argparse module will give you a lot more flexibility in playing with command line arguments.

 import argparse parser = argparse.ArgumentParser(prog='uppercase') parser.add_argument('-f','--filename', help='Any text file will do.') # filename arg parser.add_argument('-u','--uppercase', action='store_true', help='If set, all letters become uppercase.') # boolean arg args = parser.parse_args() if args.filename: # if a filename is supplied... print 'reading file...' f = open(args.filename).read() if args.uppercase: # and if boolean argument is given... print f.upper() # do your thing else: print f # or do nothing else: parser.print_help() # or print help 

So, when you start with no arguments, you get:

 /home/myuser$ python test.py usage: uppercase [-h] [-f FILENAME] [-u] optional arguments: -h, --help show this help message and exit -f FILENAME, --filename FILENAME Any text file will do. -u, --uppercase If set, all letters become uppercase. 
+1
source share

Say there is an absolute need to skip content as stdin, not the file path, because your script is in a docker container or something, but you also have other arguments that you need to pass ... so that something like this

 import sys import argparse if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('-dothis', '--DoThis', help='True or False', required=True) # add as many such arguments as u want args = vars(parser.parse_args()) if args['DoThis']=="True": content = "" for line in sys.stdin: content = content + line print "stdin - " + content 

To run this script do

$ cat abc.txt | script.py -dothis True

$ echo "hello" | script.py -dothis True

The contents of the variable will store in it everything that was printed on the left side of the channel, '|', and you could also provide script arguments.

0
source share

All Articles