# populate list of arguments args = ["mytool.py"] for opt, optname inzip("-a -x -p".split(), "address port pass".split()): args.extend([opt, str(servers[server][optname])]) args.extend("some additional command".split())
# run script p = Popen([sys.executable or'python'] + args, stdout=PIPE) # use p.stdout here... p.stdout.close() p.wait()
Обратите внимание, что передача shell=True для команд с внешним вводом представляет угрозу безопасности, как описано в предупреждении в документации.
Ответ 2
При вызове subprocess.Popen вы можете передать либо строку, либо список для выполнения команды. Если вы передаете список, элементы должны быть разделены определенным образом.
В вашем случае вам нужно разделить его примерно так:
Это потому, что если вы передаете список, Popen предполагается, что вы уже разделили командную строку на слова (значения, которые в конечном итоге будут в sys.argv), поэтому в этом нет необходимости.
То, как вы его вызываете, попытается запустить двоичный файл с именем "python mytool.py -a", что не то, что вы имели в виду.
Другой способ исправить это - объединить все слова в строку (которая Popen затем разделится - см. subprocess.list2cmdline). Но вам лучше использовать версию списка, если это возможно - это упрощает управление разделением командной строки (например, если аргументы содержат пробелы или кавычки) без необходимости возиться с заключением символов в кавычки.
Ответ 3
Ваша проблема в типе str для первого Popen аргумента. Замените его на list. Приведенный ниже код может работать:
address = servers[server]['address'] port = servers[server]['port'] pass = servers[server]['pass']
command = "python mytool.py -a %s -x %d -p %s some additional command" % (address, port, pass) p = subprocess.Popen(command.split(), stdout=subprocess.PIPE) # it is a list^^^^^^^^^^^^^^^ shell=False
Если command аргументы получены из надежного источника, вы можете сконструировать command и использовать его с shell=True таким образом:
import pipes as p command = "python mytool.py -a {} -x {} -p {} some additional command".format(p.quote(address), p.quote(port), p.quote(pass)) p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
Примечание 1: создание command с shell=True помощью потенциально небезопасно. Используйте pipes.quote() для уменьшения возможности внедрения.
Примечание 2: pipes.quote() устарел с тех пор, как python2; для python3 использования shlex модуля.
Ответ 4
Вы должны объединить команду со всей строкой:
p = subprocess.Popen("python mytool.py -a " + servers[server]['address'] + " -x " + servers[server]['port'] + " -p " + servers[server]['pass'] + " some additional command", shell=True, stdout=subprocess.PIPE)