简体   繁体   中英

Multiple arguments with stdin in Python

I have a burning question that concerns passing multiple 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 (accessed through the "cat" command) will be passed to the python script as standard input. That works fine (although a more elegant way would be nice) . But now I have to pass another argument, which is simply a word which will be used as a query (and later two words) . But I cannot find out how to do that properly, as the cat pipe will yield errors. And you can't use the standard input() in Python because it will result in an EOF-error (you cannot combine stdin and input() in Python) .

I am reasonably sure that the stdin marker with do the trick:

cat file.txt | python3.1 prearg - postarg

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

The argparse module would give you a lot more flexibility to play 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 run without 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.

Let's say there is an absolute need for one to pass content as stdin, not filepath because your script resides in a docker container or something, but you also have other arguments that you are required to pass...so do 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 variable content would store in it whatever was printed out on the left side of the pipe, '|', and you would also be able to provide script arguments.

While Steve Barnes answer will work, it isn't really 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. That way you don't have to pipe the output of the file and figure out a workaround, you can just pass the file name as another parameter.

Something like (in the 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 (in the command line):

python3.1 pythonfile.py file.txt postarg1 postarg2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM