Несколько аргументов с stdin в Python
у меня есть жгучий вопрос, который касается передачи нескольких аргументов stdin при запуске скрипта Python из терминала Unix. Рассмотрим следующую команду:
$ cat file.txt | python3.1 pythonfile.py
содержимое file.txt
(доступ через команду "cat") будет передан скрипту python в качестве стандартного ввода. Что работает (хотя более элегантный способ был бы неплохо). Но теперь я должен передать еще один аргумент, который является просто словом, которое будет использоваться как запрос (и позже двух словах). Но я не могу узнать, как это сделать правильно, так как кошачья труба даст ошибки. И вы не можете использовать стандартный input()
в Python, потому что это приведет к ошибке EOF (вы не можете объединить stdin и input()
в Python).
4 ответов
хотя ответ Стива Барнса будет работать, это не самый "питонический" способ делать вещи. Более элегантный способ-использовать аргументы sys и открывать и читать файл в самом скрипте. Таким образом, вам не нужно передавать выходные данные файла и находить обходной путь, вы можете просто передать имя файла в качестве другого параметра.
что-то вроде (в скрипте python):
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
Так (в командной строке):
python3.1 pythonfile.py file.txt postarg1 postarg2
Я достаточно уверен, что маркер stdin с do the trick:
cat file.txt | python3.1 prearg - postarg
более элегантный способ, вероятно, передать файл.txt в качестве аргумента затем откройте и прочитайте его.
на argparse модуль даст вам много больше гибкости, чтобы играть с аргументами командной строки.
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
поэтому, когда вы бежите без аргументов, вы получаете:
/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.
предположим, что существует абсолютная необходимость в передаче содержимого как stdin, а не filepath, потому что ваш скрипт находится в контейнере docker или что-то еще, но у вас также есть другие аргументы, которые вы должны передать...так что сделайте что-то вроде этого
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
чтобы запустить этот скрипт do
$ cat abc.txt | script.py -это правда!--2-->
$ echo "hello" | script.py -это правда!--2-->
содержимое переменной будет храниться в нем все, что было напечатано на левой стороне канала,"|", и вы также сможете предоставить аргументы сценария.