Понимание параметра 'shell=True' в Python subprocess
Быстрый ответ
Параметр shell=True
в модуле subprocess
Python позволяет использовать возможности командной оболочки, включая подстановочные символы, пайплайны и переменные окружения. Это может быть удобно для реализации сложных команд, но важно помнить о риске безопасности, связанном с возможностью инъекций команд. Данные всегда следует проверять на безопасность.
Например, вы можете посчитать количество строк в файлах с расширением '.py' следующим образом:
import subprocess
subprocess.run('wc -l *.py', shell=True) # Подсчет строк в файлах на Python
В данном примере параметр shell=True
позволяет интерпретировать подстановочный символ *.py
, чего не происходило бы без него. Без shell=True
пришлось бы самостоятельно формировать список файлов. Не забывайте: проверка данных на безопасность и использование shell=True
только тогда, когда это действительно необходимо, — это ключ к безопасной работе.
Что означает использование shell=True?
Риски безопасности при использовании shell=True
Используя параметр shell=True
, мы передаём командную строку в оболочку. Если данные не прошли проверку, это может привести к инъекции команд. Важно помнить о следующем:
- В первую очередь используйте
shell=False
: Это более безопасный вариант и он является значением по умолчанию. - Проведите очистку данных: Если вам всё же необходимо использовать
shell=True
, убедитесь, что вы проводите тщательную проверку данных для исключения возможных угроз, особенно если данные поступают из ненадежных источников.
Влияние shell=True на производительность
Использование shell=True
приводит к дополнительным накладным расходам из-за необходимости запуска оболочки для выполнения команды. Это может стать проблемой при частом вызове подпроцессов.
shell=True в разных операционных системах
Разные системы используют разные оболочки, из-за чего поведение shell=True
может быть непредсказуемым. На Unix-подобных системах обычно используется один из производных от Bourne shell, например, bash, а на Windows — cmd.exe
. Учтите это при использовании shell=True
.
Как безопасно использовать возможности оболочки
Прямое использование методов subprocess
Можно обойтись средствами Python без привлечения функционала оболочки:
- Перенаправление: Вместо символа
>
в командной строке используйтеstdout=subprocess.PIPE
. - Подстановочные символы: Для подстановок воспользуйтесь функцией
glob.glob('*.py')
. - Конвейеры: Для объединения команд используйте
stdout=subprocess.PIPE
при первом вызовеsubprocess
иstdin=первый_процесс.stdout
при следующих вызовах.
Использование shlex и методов os.path
- Вместо функции разбора командной строки используйте функцию
shlex.split()
. - Для расширения переменных окружения вместо интерполяции оболочки используйте функцию
os.path.expandvars
.
Избегание обращения к оболочке
Преимуществом является вызов subprocess.run(['command', 'arg1', 'arg2'])
без указания параметра shell=True
. При работе со сложными конструкциями обязательно уделяйте внимание проверке на безопасность.
Визуализация
Можно воспринимать shell=True
как приглашение переводчика, который способен разъяснить содержание книги на незнакомом языке:
Без `shell=False` (без переводчика):
- 📜 ➡️ (Читаем и ни черта не понимаем!) ❓
С `shell=True` (с переводчиком):
- 📜 ➡️ 🔊 ➡️ (Переводчик разъясняет смысл) ✅
Команды могут быть переданы потоку напрямую, или через "переводчика":
👤 ➡️ 🗣️ Командная строка: "subprocess.run(args)"
👤 ➡️ 🔊 🗣️ Переведенная команда: "subprocess.run('command', shell=True)"
Оболочка в данном случае выступает в роли переводчика, делая вашу команду понятной для операционной системы.
Расширенные функции subprocess
Работа с выводом и ошибками
subprocess.check_output()
захватывает вывод команды и вызывает исключение, если команда не может быть выполнена. Это отличает его отsubprocess.run()
.- При использовании
shell=True
следует тщательно экранировать пути, чтобы предотвратить их неправильную интерпретацию командной строкой.
Управление окружением подпроцесса
- Аргумент
env
вsubprocess.run()
позволяет изменить переменные окружения для подпроцесса. - При необходимости совмещения команд избегайте использования
shell=True
и применяйте инструменты Python из модулейitertools
илиfunctools
для обработки данных в памяти.
Полезные материалы
- subprocess — Управление подпроцессами — Документация Python 3.12.2 — официальная документация модуля
subprocess
. - Как запустить ваш скрипт или код на Python – Real Python — руководство по запуску скриптов Python.
- Кевин Лондон: Опасные функции Python, часть 2 — обзор проблем безопасности при использовании
shell=True
в subprocess. - Примеры использования модуля subprocess — практические примеры использования
subprocess
на Python. - Hackers and Slackers: выполнение команд оболочки в Python — описание различных способов вызова команд оболочки в Python.