Проблема подпроцесса Python с амперсандами
-
02-07-2019 - |
Вопрос
В настоящее время у меня возникла серьезная проблема со сценарием Python.Сценарий запускает произвольные команды через обработчик для преобразования неверных отчетов об ошибках в правильные отчеты об ошибках.
Проблема, с которой я столкнулся, заключается в том, чтобы скрипт правильно работал в Windows с командой, которая содержит амперсанды в своем пути.Я попытался процитировать команду, экранируя амперсанд с помощью ^, но ничего не помогло.У меня закончились идеи.Какие-либо предложения?
Чтобы уточнить текущие ответы:
- Я использую модуль подпроцесса
- Я передаю командную строку + аргументы в виде списка
- Проблема заключается в пути к самой команде, а не в аргументах.
- Я попробовал процитировать команду.Это вызывает
[Error 123] The filename, directory name, or volume label syntax is incorrect
ошибка - Я не использую аргумент оболочки (поэтому
shell=false
) - В случае, если это имеет значение, я перехватываю канал stderr для его обработки, но игнорирую stdout и stdin.
- В настоящее время он предназначен только для использования в Windows и работает должным образом во всех остальных случаях, которые я тестировал до сих пор.
- Команда, которая не работает:
p = subprocess.Popen(prog, stderr = subprocess.PIPE, bufsize=-1)
когда первый элемент списка «prog» содержит амперсанды.Цитирование этой первой строки не работает.
Решение
Убедитесь, что вы используете списки и не расширяете оболочку:
subprocess.Popen(['command', 'argument1', 'argument2'], shell=False)
Другие советы
Для правильного ответа потребуется больше информации.Что ты на самом деле делаешь?Как это терпит неудачу?Используете ли вы модуль подпроцесса?Вы передаете список аргументов и значение Shell=False (или не имеете аргумента оболочки) или вы на самом деле вызываете оболочку?
Попробуйте процитировать аргумент, содержащий &
wget "http://foo.com/?bar=baz&baz=bar"
Обычно это то, что нужно сделать в оболочке Linux.
"экранирование амперсанда с помощью ^"
Вы уверены ^
это escape-символ в Windows?Разве вы не должны использовать \
?
Чтобы ответить на мой собственный вопрос:
Цитирование фактической команды при передаче параметров в виде списка работает неправильно (команда является первым элементом списка), поэтому для решения проблемы я превратил список в строку, разделенную пробелами, и вместо этого передал ее в подпроцесс.
Лучшие решения по-прежнему приветствуются.
Я пробую следующую ситуацию:
exe = 'C:/Program Files (x86)/VideoLAN/VLC/VLC.exe'
url = 'http://translate.google.com/translate_tts?tl=en&q=hello+world'
subprocess.Popen([exe, url.replace("&","^&")],shell=True)
Это работает.