#python
#python
Вопрос:
Я генерирую команду, которая содержит много вложенных кавычек, а затем выполняю:
cmd = "python datax.py -p """ -Dpsql="DELETE FROM xxx WHERE date(yyy) = '2019-02-02'" """ "
os.system(cmd)
cmd может быть сгенерирован, как и ожидалось:
python datax.py -p """ -Dpsql="DELETE FROM xxx WHERE date(yyy) = '2019-02-02'" """
Но, похоже, это работает не очень хорошо. Система по-прежнему возвращает исключения, такие как '(' unexpected...
и т.д.
Я тоже пробовал '''...'''
и тоже не работает. Как решить эту проблему и есть ли какой-либо другой способ справиться с этим случаем? Любая помощь приветствуется.
Комментарии:
1. Пожалуйста, предоставьте больше кода, потому что ваш cmd-фрагмент отлично работает с моим python3.7.
2. @TobiasK Я использую python 2.7. Но когда я выполняю,
python datax.py -p .....
он все еще говорит-bash: syntax error near unexpected token
(»3. Тройные кавычки не используются в синтаксисе bash. Вы пытаетесь заключать команды оболочки в кавычки, как будто они написаны на Python.
4. @user2357112 Обратите внимание, что в целом это был бы
sh
синтаксис (dash
вероятно), который еще менее богат (беднее?) чемbash
.
Ответ №1:
Вам нужно добавить экранированную обратную косую черту \
для каждого уровня вложенности, потому что ваша оболочка, скорее всего, не поддерживает тройные кавычки. Поэтому он анализирует первые два из ваших тройных кавычек и " -Dpsql="
как строки, заключенные в кавычки, и DELETE FROM xxx WHERE date(yyy) = '2019-02-02'
как код оболочки. Но date(yyy)
недопустимый синтаксис оболочки
Пример для воспроизведения этого без вашего скрипта datax:
cmd = "python -c "print("Hello (world!)")""
os.system(cmd)
сбой с
синтаксическая ошибка возле неожиданного токена `(‘
Но
cmd = "python -c "print(\"Hello (world!)\")""
os.system(cmd)
выводит
Привет (мир!)
Я предлагаю изменить ваш код на:
cmd = "python datax.py -p " -Dpsql=\"DELETE FROM xxx WHERE date(yyy) = '2019-02-02'\"" "
Теперь ваша команда выглядит следующим образом:
python datax.py -p " -Dpsql="DELETE FROM xxx WHERE date(yyy) = '2019-02-02'""
Видите ли, существует внешний уровень кавычек для вашего -p
аргумента и внутренний уровень кавычек для кода sql.
Ответ №2:
Если вы напечатаете cmd
, вы получите:
python datax.py -p """ -Dpsql="DELETE FROM xxx WHERE date(yyy) = '2019-02-02'" """
Что os.system
делает, так это просто открывает оболочку с базовым .sh
интерпретатором и запускает ее. Такие вещи, как """
, не имеют большого значения для sh
(в основном потому, что вы не уверены, что это делает — что-то вроде пустой строки с другим началом единицы) и, конечно, скобки также плохи для sh
,
Вы должны экранировать или убедиться, что они находятся в строке. Вам придется экранировать все или убедиться, что передана правильная sh
строка. Это один из способов:
cmd = r"""python datax.py -p ' -Dpsql=" DELETE FROM xxx WHERE date(yyy) = \'2019-02-02\' " ' """
r""
сохраняет обратную косую черту как есть. Вывод этого приводит к:
python datax.py -p ' -Dpsql=" DELETE FROM xxx WHERE date(yyy) = 2019-02-02 " '
Лучшим вариантом, я думаю, было бы просто использовать:
cmd = r"""python datax.py -p -Dpsql=" DELETE FROM xxx WHERE date(yyy) = '2019-02-02' " """
Итак, я опустил один уровень '
. Теперь просто исправьте datax.py
синтаксический анализ argv
, чтобы лучше соответствовать вашим потребностям (возьмите все после -p
здесь). Это также упростило бы его прямой вызов. При печати:
python datax.py -p -Dpsql=" DELETE FROM xxx WHERE date(yyy) = '2019-02-02' "
argparse
хорошо справляется с этими задачами.