Передача аргументов, которые включают двойные кавычки, в подпроцесс с использованием Python

Я ищу способ передать аргумент, содержащий двойные кавычки, в модуль подпроцесса python без экранирования двойных кавычек.

Я видел, как этот вопрос задавался несколько раз, когда аргумент был заключен в кавычки, но обычно ответ заключается в том, чтобы удалить кавычки. Проблема, с которой я столкнулся, заключается в том, что кавычки являются частью аргумента и должны быть переданы в скрипт без добавления обратной косой черты перед каждой кавычкой.

пример:

Я вызываю subprocesTest.bat, простой пакетный скрипт, который принимает аргумент и повторяет его:

echo "%~1"

Я вызываю пакетный скрипт из python с аргументом, который включает кавычки:

import subprocess
test_string = 'Bill said "Hi!"'
cmd = ["subprocesTest.bat",
       test_string
       ]

p = subprocess.Popen(cmd)
p.wait()

ожидаемый результат:

"Билл сказал "Привет!""

фактический результат:

"Билл сказал \"Привет!\""

Я могу получить ожидаемый результат при вызове того же пакетного сценария из командной строки следующим образом:

subprocesTest.bat "Билл сказал "Привет!""

Глядя на источник, функция subprocess.py list2cmdline задокументирована с помощью:

 3) A double quotation mark preceded by a backslash is
   interpreted as a literal double quotation mark.

Однако, если я прохожу через эту функцию, я не вижу способа передать двойную кавычку без добавления обратной косой черты:

        elif c == '"':
            # Double backslashes.
            result.append('\\' * len(bs_buf)*2)
            bs_buf = []
            result.append('\\"')

Итак, у меня два вопроса...

  • Можно ли передать аргумент в подпроцесс, который содержит двойную кавычку без обратной косой черты
  • Если это невозможно, может ли кто-нибудь объяснить мне, почему функция была разработана таким образом? Третий пункт в строке документа функции, по-видимому, указывает на то, что я могу передать буквальную кавычку, добавив обратную косую черту, но это не дает того поведения, которое я искал. Я неправильно читаю документ?

Вот другие темы, в которых этот вопрос задается и работает без использования кавычек:

Я не вижу ответа на ситуацию, когда я действительно хочу передать кавычки в своем аргументе


person BetterOffEd    schedule 05.06.2013    source источник
comment


Ответы (1)


1) Да, но, возможно, не в Windows и/или с файлом .bat. Например, что происходит, когда вы запускаете эквивалент Windows:

import subprocess

test_string = 'Bill said "Hi!"'

cmd = ["./myprog.py",
       test_string
       ]

p = subprocess.Popen(cmd)
p.wait()

myprog.py:

#!/usr/bin/env python

import sys

print '"{}"'.format(sys.argv[1])

2) Ну, следующее кажется немного двусмысленным:

"Bill said "Hi!""

Это цитируемая строка:

"Bill said " 

за которой следует строка без кавычек:

Hi!

за которой следует пустая строка в кавычках:

""

?

person 7stud    schedule 06.06.2013
comment
1) ваш пример myprog.py работает только потому, что подпроцесс добавляет обратную косую черту, которая, как я полагаю, используется для выхода из двойных кавычек, когда python читает аргументы. Если я вызову тот же сценарий myprog.py из командной строки Windows и передам Биллу привет! как аргумент, кавычки вокруг Hi! пропадать. Я предполагаю, что это причина, по которой обратная косая черта всегда предшествует двойной кавычке. - person BetterOffEd; 06.06.2013
comment
2) Это хороший момент. Я не уверен, как командная строка Windows интерпретирует аргумент, я просто знаю, что он не интерпретируется одинаково при передаче через подпроцесс. Возможно, лучшим примером был бы простой сценарий, который принимает измерения в качестве параметров. Я хочу передать 16, чтобы обозначить 16 дюймов, используя подпроцесс, но подпроцесс преобразует мой аргумент в 16\, что не соответствует моему пакетному сценарию расстояния. - person BetterOffEd; 06.06.2013