Как транслировать ввод в 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