Чтение со стандартного ввода с системным argv - PullRequest
0 голосов
/ 27 июня 2018

Я пытаюсь поместить файл CSV в стандартный вывод и затем передать распечатанный вывод в качестве входных данных в программу на языке Python, которая также принимает системный вектор аргумента с 1 аргументом. Я столкнулся с проблемой, которая, я думаю, напрямую связана с тем, как функция Python fileinput.input () реагирует на занятие дескриптора файла stdin.

generic_user% cat my_data.csv | python3 my_script.py myarg1

Вот пример программы на Python:

import sys, fileinput

def main(argv):
    print("The program doesn't even print this")
    data_list = []
    for line in fileinput.input():
        data_list.append(line)

if __name__ == "__main__":
    main(sys.argv)

Если я попытаюсь запустить этот пример программы с помощью приведенной выше команды терминала и без аргумента myarg1, программа сможет оценить и проанализировать стандартный вывод данных, выводимых из файла CSV.

Если я запустлю программу с аргументом myarg1, она выдаст ошибку FileNotFoundError, непосредственно связанную с myarg1, не существующим в виде файла.

FileNotFoundError: [Errno 2] No such file or directory: 'myarg1'

Может ли кто-нибудь подробно объяснить, почему такое поведение имеет место в Python и как обрабатывать логику так, чтобы программа на Python могла сначала обработать данные stdin, прежде чем argv перезапишет дескриптор stdin?

Ответы [ 3 ]

0 голосов
/ 27 июня 2018

Это по проекту . Концепты fileinput считали, что были случаи, когда чтение из stdin было бы бессмысленным, и просто предоставляли способ специально добавлять stdin в список файлов. Согласно справочной документации:

import fileinput
for line in fileinput.input():
    process(line)

Это перебирает строки всех файлов, перечисленных в sys.argv [1:], по умолчанию sys.stdin, если список пуст. Если имя файла '-', оно также заменяется sys.stdin .

Просто сохраните ваш код и используйте: generic_user% cat my_data.csv | python3 my_script.py - myarg1

для чтения стандартного ввода до myarg1 файла или если вы хотите прочитать его после: ... python3 my_script.py myarg1 -

0 голосов
/ 27 июня 2018

fileinput реализует шаблон, общий для утилит Unix:

  • Если утилита вызывается с аргументами командной строки, это файлы для чтения.
  • Если он вызывается без аргументов, читать из стандартного ввода.

То есть fileinput работает точно так, как задумано. Непонятно, для чего вы используете аргументы командной строки, но если вы не хотите прекратить использовать fileinput, вам следует изменить sys.argv, прежде чем вызывать его.

some_keyword = sys.argv[1]
sys.argv = sys.argv[:1]      # Retain only argument 0, the command name

for line in fileinput.input():
    ...
0 голосов
/ 27 июня 2018

Вы можете читать с stdin напрямую:

import sys

def main(argv):
    print("The program doesn't even print this")
    data_list = []
    for line in iter(sys.stdin):
        data_list.append(line)

if __name__ == "__main__":
    main(sys.argv)

Вы пытаетесь получить доступ к файлу, который еще не был создан, поэтому fileinput не может открыть его, но, поскольку вы передаете данные, вам это не нужно.

...