2015-02-11 2 views
1

Как передать команду sed на popen без использования строки?Как передать команду `sed` для« popen »без использования строковой строки?

Когда я передать патч в команду popen в виде списка я получаю сообщение об ошибке: unterminated address regex (см первого примера)

>>> COMMAND = ['sed', '-i', '-e', "\$amystring", '/home/map/myfile'] 
>>> subprocess.Popen(COMMAND).communicate(input=None) 
sed: -e expression #1, char 11: unterminated address regex 

с использованием сырой строки формы она работает, как ожидалось:

>>> COMMAND = r"""sed -i -e "\$amystring" /home/map/myfile""" 
>>> subprocess.Popen(COMMAND, shell=True).communicate(input=None) 

Мне очень нравится проходить "\$amystring" как элемент в списке. Пожалуйста, избегайте ответы как

>>> COMMAND = r" ".join(['sed', '-i', '-e', "\$amystring", '/home/map/myfile'] 
>>> subprocess.Popen(COMMAND, shell=True).communicate(input=None) 
+0

, но он показывает (нет, нет) для меня. –

+0

Что не так с командой 'command = 'sed -i -e" \ $ amystring "/ home/map/myfile'' – Jkdc

+2

Реальный вопрос: зачем вы обходитесь с sed, когда используете Python? Вы посмотрели на модуль re? –

ответ

2

Различия между этими двумя формами является то, что с shell=True в качестве аргумента, строка получает передается как к оболочке, которая затем интерпретирует его. Это приводит к (с bash):

sed -i -e \$amystring /home/map/myfile 

Выполняется.

С списком args и значением по умолчанию shell=False, python вызывает исполняемый файл непосредственно с аргументами в списке. В этом случае символьная строка передается в СЭД,

sed -i -e '\$amystring' /home/map/myfile 

'\$amystring' и не является допустимым sed выражение. В этом случае вам нужно будет позвонить

>>> COMMAND = ['sed', '-i', '-e', "$amystring", '/home/map/myfile'] 
>>> subprocess.Popen(COMMAND).communicate(input=None) 

так как для оболочки не требуется экранирование.

+0

Спасибо за подсказку. В самом деле, я не понял/понял, что $ не нужно менять. – wolfrevo

0

Нет такой вещи, как необработанная строка. Есть только сырые строки литералы.

Литерал - это то, что вы вводите в исходный код Python.

r'\$amystring' и '\\$amystring' те же строки объекты несмотря представлены с использованием различных строк строковых литералов.

Как @Jonathan Villemaire-Krajden said: если нет shell=True, то вам не нужно избегать $ Оболочка метасимвол. Вам нужно только это, если вы запустите команду в оболочке:

$ python -c 'import sys; print(sys.argv)' "\$amystring" 
['-c', '$amystring'] 

Примечание: на выходе нет обратной косой черты.

Не используйте .communicate(), если вы не перенаправлять стандартные потоки с помощью PIPE, вы могли бы использовать call(), check_call() вместо:

import subprocess 

rc = subprocess.call(['sed', '-i', '-e', '$amystring', '/home/map/myfile']) 

Для эмуляции $amystring патч в команду в Python (± строки):

with open('/home/map/myfile', 'a') as file: 
    print('mystring', file=file) 
Смежные вопросы