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"')