callProcess = subprocess.Popen(['ls', '-l']) # without shell
Оба работают. Прочитав документы, я узнал, что shell=True означает выполнение кода через оболочку. Таким образом, это означает, что при отсутствии процесс запускается напрямую.
Итак, что я должен предпочесть в моем случае - мне нужно запустить процесс и получить его выходные данные. Какую выгоду я получу от вызова его из оболочки или вне ее?
Переведено автоматически
Ответ 1
Преимущество отказа от вызова через оболочку заключается в том, что вы не вызываете "таинственную программу". В POSIX переменная окружения SHELL управляет, какой двоичный файл вызывается как "оболочка". В Windows нет потомка bourne shell, только cmd.exe.
Таким образом, вызов оболочки вызывает программу по выбору пользователя и зависит от платформы. Вообще говоря, избегайте вызовов через оболочку.
Вызов через оболочку позволяет вам расширять переменные среды и глобусы файлов в соответствии с обычным механизмом оболочки. В системах POSIX оболочка расширяет глобусы файлов до списка файлов. В Windows глобальный файл (например, "*. *") в любом случае не расширяется оболочкой (но переменные среды в командной строке расширяются на cmd.exe).
Если вы думаете, что вам нужны расширения переменных среды и глобусы файлов, изучите ILS атаки 1992 года на сетевые службы, которые выполняли вызовы подпрограмм через оболочку. Примеры включают различные sendmail бэкдоры, включающие ILS.
Подводя итог, используйте shell=False.
Ответ 2
>>> import subprocess >>> subprocess.call('echo $HOME') Traceback (most recent call last): ... OSError: [Errno 2] No such file or directory >>> >>> subprocess.call('echo $HOME', shell=True) /user/khong 0
Установка аргумента shell в значение true приводит к тому, что подпроцесс запускает промежуточный процесс shell и сообщает ему выполнить команду. Другими словами, использование промежуточной оболочки означает, что переменные, глобальные шаблоны и другие специальные функции оболочки в командной строке обрабатываются перед запуском команды. Здесь, в примере, $HOME был обработан перед командой echo. На самом деле, это случай команды с расширением оболочки, в то время как команда ls -l рассматривается как простая команда.
An example where things could go wrong with Shell=True is shown here
>>> 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 / # THIS WILL DELETE EVERYTHING IN ROOT PARTITION!!! >>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...
Executing programs through the shell means that all user input passed to the program is interpreted according to the syntax and semantic rules of the invoked shell. At best, this only causes inconvenience to the user, because the user has to obey these rules. For instance, paths containing special shell characters like quotation marks or blanks must be escaped. At worst, it causes security leaks, because the user can execute arbitrary programs.
shell=True is sometimes convenient to make use of specific shell features like word splitting or parameter expansion. However, if such a feature is required, make use of other modules are given to you (e.g. os.path.expandvars() for parameter expansion or shlex for word splitting). This means more work, but avoids other problems.