Много вложенных кавычек

#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 хорошо справляется с этими задачами.