Ответ 1
Вы должны добавить shell=True
для выполнения команды оболочки. check_output
пытается найти исполняемый файл: date | grep -o -w '"+tz+"'' | wc -w
, и он не может его найти. (не знаю, почему вы удалили важную информацию из сообщения об ошибке).
См. разницу между:
>>> subprocess.check_output('date | grep 1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.4/subprocess.py", line 603, in check_output
with Popen(*popenargs, stdout=PIPE, **kwargs) as process:
File "/usr/lib/python3.4/subprocess.py", line 848, in __init__
restore_signals, start_new_session)
File "/usr/lib/python3.4/subprocess.py", line 1446, in _execute_child
raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'date | grep 1'
И:
>>> subprocess.check_output('date | grep 1', shell=True)
b'gio 19 giu 2014, 14.15.35, CEST\n'
Прочитайте документацию о Часто используемые аргументы для получения дополнительной информации о аргументе shell
и о том, как он изменяет интерпретацию других аргументов.
Обратите внимание, что вы должны стараться избегать использования shell=True
, так как порождение оболочки может быть угрозой безопасности (даже если вы не выполняете ненадежные входные атаки, такие как Shellshock все еще можно выполнить!).
Документация для модуля подпроцесса содержит небольшой раздел о замене оболочки оболочки.
Вы можете сделать это, создав два процесса в python и используя subprocess.PIPE
:
date_proc = subprocess.Popen(['date'], stdout=subprocess.PIPE)
grep_proc = subprocess.check(['grep', '1'], stdin=date_proc.stdout, stdout=subprocess.PIPE)
date_proc.stdout.close()
output = grep_proc.communicate()[0]
Вы можете написать некоторую простую функцию-обертку, чтобы легко определить конвейеры:
import subprocess
from shlex import split
from collections import namedtuple
from functools import reduce
proc_output = namedtuple('proc_output', 'stdout stderr')
def pipeline(starter_command, *commands):
if not commands:
try:
starter_command, *commands = starter_command.split('|')
except AttributeError:
pass
starter_command = _parse(starter_command)
starter = subprocess.Popen(starter_command, stdout=subprocess.PIPE)
last_proc = reduce(_create_pipe, map(_parse, commands), starter)
return proc_output(*last_proc.communicate())
def _create_pipe(previous, command):
proc = subprocess.Popen(command, stdin=previous.stdout, stdout=subprocess.PIPE)
previous.stdout.close()
return proc
def _parse(cmd):
try:
return split(cmd)
except Exception:
return cmd
С помощью этого вы можете написать:
pipeline('date | grep 1')
Или:
pipeline('date', 'grep 1')
Или:
pipeline(['date'], ['grep', '1'])