Как избежать / использовать одинарные кавычки в команде os.system с python 2? - PullRequest
0 голосов
/ 04 сентября 2018

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

os.system("imapsync --host1 %s --user1 %s --password1 '%s' --host2 %s --user2 %s --password2 '%s' --ssl1 --no-modulesversion --ssl2" % (fromHost, emails, passwords, toHost, emails, passwords))

Дело в том, что пароли часто содержат специальные символы, например: djDJS * ^ %%% ^ &)

этот инструмент imapsync позволяет использовать такие символы, если они заключены в одинарные кавычки: 'djDJS * ^ %%% ^ &)'

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

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Лучший формат для передачи строковых параметров в Python - это использовать метод форматирования строки. Вы могли бы сделать что-то вроде этого:

line_command = "imapsync --host1 {fromHost} --user1 {emails} --password1 '\"{passwords}\"' --host2 {toHost} --user2 {emails} --password2 '\"{passwords}\"' --ssl1 --no-modulesversion --ssl2".format(fromHost=fromHost, emails=emails, passwords=passwords, toHost=toHost)
os.system(line_command)
0 голосов
/ 04 сентября 2018

Просмотрев документацию по imapsync, я нашел рекомендацию заключать пароли в двойные кавычки в одинарные кавычки, чтобы избежать распространенных проблем .

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

Есть также две вещи, которые вы можете сделать, чтобы сделать ваш код еще лучше. Во-первых, вы можете использовать синтаксис .format для форматирования строки вместо старого синтаксиса %.

Второй заменить os.system на subprocess.Popen. Это позволяет вам разбить командную строку на список всех аргументов, что выглядит более понятным.

Ваш новый код будет выглядеть как

import subprocess

args = [
  "imapsync",
  "--host1",
  fromHost,
  "--user1",
  emails,
  "--password1",
  "'\"{}\"'".format(passwords),
  "--host2",
  toHost,
  "--user2",
  emails,
  "--password2",
  "'\"{}\"'".format(passwords),
  "--ssl1",
  "--no-modulesversion",
  "--ssl2"
]

p = subprocess.Popen(args, stdout=subprocess.PIPE)

output = p.communicate()[0]

print(output)

В этом примере Popen.communicate используется для сбора выходных данных команды imapsync в виде строки. Метод communicate возвращает кортеж с выходами подпроцесса в потоки stdout и stderr.

Если вы также хотите прочитать вывод в stderr из подпроцесса, измените код следующим образом:

p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

output, errors = p.communicate()

print(output)
print(errors)
...