Python: вызов подпроцесса с оболочкой = False не работает
Я использую Python script для вызова виртуальной машины Java. Выполняется следующая команда:
subprocess.call(["./rvm"], shell=False) # works
subprocess.call(["./rvm xyz"], shell=True) # works
Но,
subprocess.call(["./rvm xyz"], shell=False) # not working
не работает. Документация Python, чтобы избежать shell=True
.
Ответы
Ответ 1
Вам нужно разбить команды на отдельные строки:
subprocess.call(["./rvm", "xyz"], shell=False)
Строка будет работать, когда shell=True
, но вам нужен список аргументов, когда shell=False
Модуль shlex полезен, тем более, для более сложных команд и обработки ввода, но полезно узнать:
import shlex
cmd = "python foo.py"
subprocess.call(shlex.split(cmd), shell=False)
shlex tut
Ответ 2
Если вы хотите использовать shell=True
, это законно, иначе оно было бы удалено из стандартной библиотеки. В документации не говорится, чтобы избежать этого, говорит:
Выполнение команд оболочки, которые включают неанитированный ввод из ненадежного источника, делает программу уязвимой для инъекции оболочки, серьезную ошибку безопасности, которая может привести к произвольному выполнению команды. По этой причине использование shell=True
сильно обескураживается в случаях, когда командная строка построена из внешнего ввода.
Но в вашем случае вы не создаете команду с пользовательского ввода, ваша команда постоянна, поэтому ваш код не представляет проблемы с вводом оболочки. Вы контролируете, что будет выполнять оболочка, и если ваш код не является вредоносным как таковым, вы в безопасности.
Пример инъекции оболочки
Чтобы объяснить, почему инъекция оболочки настолько плоха, это пример, используемый в документации:
>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / #
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...
Изменить
С дополнительной информацией, которую вы предоставили для редактирования вопроса, придерживайтесь Padraic ответа. Вы должны использовать shell=True
только при необходимости.
Ответ 3
В дополнение к ответу Enrico.bacis есть два способа вызова программ. С помощью shell=True
введите полную командную строку. С помощью shell=False
введите список.
Если вы используете трюки оболочки, такие как *.jpg
или 2> /dev/null
, используйте shell=True
; но в целом я предлагаю shell=False
- он более прочен, как сказал Энрико.
Источник
import subprocess
subprocess.check_call(['/bin/echo', 'beer'], shell=False)
subprocess.check_call('/bin/echo beer', shell=True)
Выход
beer
beer
Ответ 4
Вместо использования каталога имен файлов добавьте перед ним слово python
, при условии, что вы добавили путь python к своим переменным окружения. Если вы не уверены, вы всегда можете повторно запустить установщик python, при условии, что у вас есть новая версия python.
Вот что я имею в виду:
import subprocess
subprocess.Popen('python "C:/Path/To/File/Here.py"')