На самом деле вы не выполняете команду bash
. Вы запускаете исполняемый файл напрямую и передаете ему аргументы.
Попробуйте следующий сценарий, чтобы увидеть, что происходит:
import subprocess
p = subprocess.Popen(["echo", "a", "b", "|", "rev"], stdout=subprocess.PIPE)
print p.communicate()
Результатом будет:
('a b | rev\n', None)
Перенаправления не происходит, знак "|" передается буквально. То есть, как если бы вы набрали find ... \ | параллельно ...
. Таким образом ошибка.
Есть два способа исправить это.
Простой способ: передать shell = True
в subprocess.Popen
. Это пропустит его через оболочку со всем, что влечет за собой. Если вы это сделаете, вам также необходимо передать строку вместо массива:
import subprocess
p = subprocess.Popen ("echo ab | rev", stdout = subprocess.PIPE, shell = True )
print p.communicate ()
# Результат: ('ba \ n', Нет)
Если вы сделаете это, будьте очень осторожны с подстановкой аргументов в вашу строку .
Надежный способ: открыть два процесса с помощью Python и соединить их по конвейеру.
import subprocess
# Первая команда
p1 = subprocess.Popen (["echo", "a", "b"], stdout = subprocess.PIPE)
# Вход второй команды связан с выходом первой
p2 = subprocess.Popen (["rev"], stdin = p1.stdout, stdout = subprocess.PIPE)
# Прочитать из p2, чтобы получить output
print p2.communicate ()
# Result: ('ba \ n', None)
Это более надежно и не порождает дополнительную оболочку, но, с другой стороны, она больше печатает.Если вы сделаете это, то обратите внимание, что никакая замена оболочки не происходит . В вашем случае это не похоже, что вам это нужно, но если вы хотите использовать, скажем, ~
, вам придется получить его через Python (например, os.getenv ( «ДОМ»)
).
Второй ищет строки, содержащие хотя бы один символ, и поэтому не находит пустые строки, в которых нет символов. Если вы хотите оба, попробуйте следующее:
grep -e ^[^#] -e ^$ /etc/apache2/apache2.conf
grep -v ^#
#
#
, поэтому ex не включены тогда как
grep ^[^#]
#