Как транслировать ввод в python построчно из программы linux?

Я хочу передать вывод ps -ef в питон построчно.

Сценарий, который я использую это (first.py) -

#! /usr/bin/python

import sys

for line in sys.argv:
   print line

К сожалению, "строка" разбита на слова, разделенные пробелами. Так, например, если я сделаю

echo "days go by and still" | xargs first.py

вывод я получаю

./first.py
days
go
by
and
still

Как написать скрипт такой, чтобы вывод

./first.py
days go by and still

?

4 ответа

Решение

Я не совсем понимаю, почему вы хотите использовать аргументы командной строки вместо простого чтения из стандартного ввода. В Python есть простая идиома для перебора строк в stdin:

import sys

for line in sys.stdin:
    sys.stdout.write(line)

Мой пример использования:

$ echo -e "first line\nsecond line" | python python_iterate_stdin.py 
first line
second line

Ваш пример использования:

$ echo "days go by and still" | python python_iterate_stdin.py
days go by and still

Что вы хотите popen, что позволяет напрямую читать вывод команды, как если бы вы читали файл:

import os
with os.popen('ps -ef') as pse:
    for line in pse:
        print line
        # presumably parse line now

Обратите внимание, что, если вы хотите более сложный анализ, вам придется копаться в документации subprocess.Popen,

Другой подход - использовать input() функция (код для Python 3).

while True:
        try:
            line = input()
            print('The line is:"%s"' % line)
        except EOFError:
            # no more information
            break

Разница между ответом и ответом, полученным доктором Яном-Филипом Герке, заключается в том, что теперь каждая из строк не имеет новой строки (\n) в конце.

Я знаю, что это действительно устарело, но вы можете попробовать

      #! /usr/bin/python
import sys
print(sys.argv, len(sys.argv))

if len(sys.argv) == 1:
    message = input()
else:
    message = sys.argv[1:len(sys.argv)]

print('Message:', message)

и я проверил это так:

      $ ./test.py
['./test.py'] 1
this is a test
Message: this is a test

$ ./test.py this is a test
['./test.py', 'this', 'is', 'a', 'test'] 5
Message: ['this', 'is', 'a', 'test']

$ ./test.py "this is a test"
['./test.py', 'this is a test'] 2
Message: ['this is a test']

$ ./test.py 'this is a test'
['./test.py', 'this is a test'] 2
Message: ['this is a test']

$ echo "This is a test" | ./test.py
['./test.py'] 1
Message: This is a test

Или, если вы хотите, чтобы сообщение было одной строкой каждый раз, тогда

          message = ' '.join(sys.argv[1:len(sys.argv)])

сделал бы трюк на линии 8

Другие вопросы по тегам