Понимание параметра 'shell=True' в Python subprocess

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Параметр shell=True в модуле subprocess Python позволяет использовать возможности командной оболочки, включая подстановочные символы, пайплайны и переменные окружения. Это может быть удобно для реализации сложных команд, но важно помнить о риске безопасности, связанном с возможностью инъекций команд. Данные всегда следует проверять на безопасность.

Например, вы можете посчитать количество строк в файлах с расширением '.py' следующим образом:

Python
Скопировать код
import subprocess
subprocess.run('wc -l *.py', shell=True)  # Подсчет строк в файлах на Python

В данном примере параметр shell=True позволяет интерпретировать подстановочный символ *.py, чего не происходило бы без него. Без shell=True пришлось бы самостоятельно формировать список файлов. Не забывайте: проверка данных на безопасность и использование shell=True только тогда, когда это действительно необходимо, — это ключ к безопасной работе.

Кинга Идем в IT: пошаговый план для смены профессии

Что означает использование shell=True?

Риски безопасности при использовании shell=True

Используя параметр shell=True, мы передаём командную строку в оболочку. Если данные не прошли проверку, это может привести к инъекции команд. Важно помнить о следующем:

  1. В первую очередь используйте shell=False: Это более безопасный вариант и он является значением по умолчанию.
  2. Проведите очистку данных: Если вам всё же необходимо использовать shell=True, убедитесь, что вы проводите тщательную проверку данных для исключения возможных угроз, особенно если данные поступают из ненадежных источников.

Влияние shell=True на производительность

Использование shell=True приводит к дополнительным накладным расходам из-за необходимости запуска оболочки для выполнения команды. Это может стать проблемой при частом вызове подпроцессов.

shell=True в разных операционных системах

Разные системы используют разные оболочки, из-за чего поведение shell=True может быть непредсказуемым. На Unix-подобных системах обычно используется один из производных от Bourne shell, например, bash, а на Windows — cmd.exe. Учтите это при использовании shell=True.

Как безопасно использовать возможности оболочки

Прямое использование методов subprocess

Можно обойтись средствами Python без привлечения функционала оболочки:

  1. Перенаправление: Вместо символа > в командной строке используйте stdout=subprocess.PIPE.
  2. Подстановочные символы: Для подстановок воспользуйтесь функцией glob.glob('*.py').
  3. Конвейеры: Для объединения команд используйте stdout=subprocess.PIPE при первом вызове subprocess и stdin=первый_процесс.stdout при следующих вызовах.

Использование shlex и методов os.path

  • Вместо функции разбора командной строки используйте функцию shlex.split().
  • Для расширения переменных окружения вместо интерполяции оболочки используйте функцию os.path.expandvars.

Избегание обращения к оболочке

Преимуществом является вызов subprocess.run(['command', 'arg1', 'arg2']) без указания параметра shell=True. При работе со сложными конструкциями обязательно уделяйте внимание проверке на безопасность.

Визуализация

Можно воспринимать shell=True как приглашение переводчика, который способен разъяснить содержание книги на незнакомом языке:

Markdown
Скопировать код
Без `shell=False` (без переводчика):
- 📜 ➡️ (Читаем и ни черта не понимаем!) ❓
  
С `shell=True` (с переводчиком):
- 📜 ➡️ 🔊 ➡️ (Переводчик разъясняет смысл) ✅

Команды могут быть переданы потоку напрямую, или через "переводчика":

Markdown
Скопировать код
👤 ➡️ 🗣️ Командная строка: "subprocess.run(args)"
👤 ➡️ 🔊 🗣️ Переведенная команда: "subprocess.run('command', shell=True)"

Оболочка в данном случае выступает в роли переводчика, делая вашу команду понятной для операционной системы.

Расширенные функции subprocess

Работа с выводом и ошибками

  • subprocess.check_output() захватывает вывод команды и вызывает исключение, если команда не может быть выполнена. Это отличает его от subprocess.run().
  • При использовании shell=True следует тщательно экранировать пути, чтобы предотвратить их неправильную интерпретацию командной строкой.

Управление окружением подпроцесса

  • Аргумент env в subprocess.run() позволяет изменить переменные окружения для подпроцесса.
  • При необходимости совмещения команд избегайте использования shell=True и применяйте инструменты Python из модулей itertools или functools для обработки данных в памяти.

Полезные материалы

  1. subprocess — Управление подпроцессами — Документация Python 3.12.2 — официальная документация модуля subprocess.
  2. Как запустить ваш скрипт или код на Python – Real Python — руководство по запуску скриптов Python.
  3. Кевин Лондон: Опасные функции Python, часть 2 — обзор проблем безопасности при использовании shell=True в subprocess.
  4. Примеры использования модуля subprocess — практические примеры использования subprocess на Python.
  5. Hackers and Slackers: выполнение команд оболочки в Python — описание различных способов вызова команд оболочки в Python.