Как узнать операционную систему компьютера python

Обновлено: 06.07.2024

Чтобы просто увидеть IP-адрес и другие сетевые настройки, вам нужно перейти в командную строку и запустить команду ipconfig / all. Ситуация — одна из самых распространенных для эникейщиков и удаленных шаманов, но, по крайней мере, ее можно быстро решить. Но если вам нужно собрать более серьезный набор информации о машине, с которой вы теперь будете работать, без автоматизации вам не обойтись. Этим и займемся.

Доступ к компьютерной информации без санкции является преступлением. Ни автор, ни редакция не несут ответственности за ваши действия.

Задачи

Да­вай сна­чала обри­суем, что мы вооб­ще пла­ниру­ем делать. Я пла­нирую собирать сле­дующую информа­цию:

  1. IP-адрес.
  2. MAC-адрес.
  3. Имя поль­зовате­ля.
  4. Тип опе­раци­онной сис­темы.
  5. Ско­рость работы сис­темы.
  6. Вре­мя.
  7. Скрин­шот.
  8. Ско­рость интернет‑соеди­нения.
  9. Мо­дель про­цес­сора.

И отправ­лять­ся это все будет пря­миком тебе в телегу через спе­циаль­ный бот.

Инструменты

Сначала рассмотрим, где мы будем писать код. Вы можете писать код в обычном блокноте Windows, но мы будем использовать специальную среду разработки Python — PyCharm. Установка и настройка просты как два рубля: скачайте установщик, запустите его — и нажмите «Далее» при появлении такой кнопки.
Еще нам нужен Python. Буду использовать версию 3.9.0 — уверен, что с ней все работает.

Основа программы

Для отправки данных я решил использовать робота Telegram. Вы можете создать его через BotFather, а затем сохранить токен своего создания. Вы не можете опубликовать его — любой, кто получит этот токен, сможет взять под контроль вашего бота.

Для под­клю­чения к Bot API «телеги» нуж­ны все­го две строч­ки:

Что­бы оце­нить быс­тро­дей­ствие, мож­но написать еще пару строк. Весь даль­нейший код рас­положим меж­ду ними. Опи­сан­ное выше под­клю­чение бота уже впи­сано сюда

Те­перь перей­дем собс­твен­но к сбо­ру дан­ных.

Сбор данных

Я не буду дол­го ходить вок­руг да око­ло и сра­зу нач­ну раз­бирать сек­цию импорта.

Те­перь крат­ко рас­смот­рим, что дела­ет каж­дый модуль. Если какие‑то фун­кции тебе не нуж­ны, выб­роси стро­ку импорта модуля и код, который исполь­зует этот модуль. Все прос­то!

Итак, за работу с ОС и локаль­ными ресур­сами отве­чают эти четыре модуля:

  • getpass нужен для опре­деле­ния информа­ции о поль­зовате­ле;
  • os исполь­зуем для вза­имо­дей­ствия с фун­кци­ями ОС, вро­де вызова внеш­них исполня­емых фай­лов;
  • psutil работа­ет с некото­рыми низ­коуров­невыми сис­темны­ми фун­кци­ями;
  • platform пре­дос­тавит информа­цию об ОС.

Эти­ми модуля­ми реали­зова­ны сетевые вза­имо­дей­ствия:

  • socket — для работы с сокета­ми и получе­ния IP-адре­сов;
  • getnode получа­ет MAC-адрес машины;
  • speedtest замеря­ет харак­терис­тики интернет‑соеди­нения;
  • telebot сде­лает всю рутину по работе с Telegram-ботом.

Слу­жеб­ные при­моч­ки, которые труд­но отнести к катего­риям выше:

  • datetime поз­волит опре­делить вре­мя работы прог­раммы;
  • pyautogui работа­ет с GUI;
  • PIL. Image — для сня­тия скрин­шота.

Пос­ле это­го нам тре­бует­ся узнать основные ста­биль­ные харак­терис­тики сис­темы: IP- и MAC-адре­са, имя поль­зовате­ля и ОС:

Стро­ки кода снаб­жены ком­мента­риями и в пояс­нени­ях не нуж­дают­ся.

Скорость интернет-соединения

Важно понимать, что измерения не должны быть слишком точными, поскольку мы не можем легко проверить, какая часть канала используется другими программами или даже другими устройствами в сети. Если вы подключились к рабочей станции удаленно, ваше соединение тоже что-то потребляет. Исправление этого не было реализовано в программе из-за очень низкой точности и качества исполнения.

Часовой пояс и время

Частота процессора

Это может помочь определить причину, по которой ваш компьютер замедляется: если процессор постоянно развивается, но программы дают сбой, процессор устарел, а если он простаивает, виновата программа. И просто общее представление о железе.

Глубокий фингерпринтинг

В этой статье специально не рассказывается, как получить идентификатор жесткого диска или установленный идентификатор Windows GUID — мы не пишем руководство для рекламодателей, а практикуемся в программировании. Однако вы можете легко добавить коллекцию такой информации с помощью утилиты консоли wmic. Его вывод можно проанализировать с помощью скрипта Python, поэтому вам даже не нужно писать дополнительные привязки. На скриншоте показан пример получения серийного номера BIOS.


Скриншот рабочего стола

bot . send_message ( message . chat . id , "[ Error]: Location not found!" )

Тут все тоже мак­сималь­но прос­то, а за собс­твен­но сня­тие скрин­шота отве­чает толь­ко пос­ледняя стро­ка кода. Осталь­ное мы исполь­зуем для кор­рек­тной обра­бот­ки вхо­дящей коман­ды бота.

Запись в файл

После того, как все будет сделано, мы можем перейти к окончательному сбору и отправке данных. Мы создаем готовый файл с нашими данными: если был использован максимальный сбор информации, а точнее весь приведенный выше код, мы будем использовать этот набор данных, в противном случае мы удалим данные, которые вам не нужны:

bot . send_message ( message . chat . id , "[ Error]: Location not found!" )

Отправка данных

Те­перь допол­ним код выше, что­бы он еще и фай­лы отправ­лял.

Сна­чала ука­зыва­ется под­пись к скрин­шоту, потом чита­ем и отправ­ляем фай­лы в виде фото и докумен­та, затем зачища­ем сле­ды и зак­рыва­ем соеди­нение с ботом. Ничего слож­ного!

Ес­тес­твен­но, если нам не нужен, к при­меру, скрин­шот, мы можем вырезать код его отправ­ки, получив такой вари­ант:

Что­бы бот гаран­тирован­но отправ­лял все сооб­щения тебе, ука­жи вмес­то message. chat. id ID чата с собой. Его мож­но узнать через бот GetMyID.

Чтобы не перетаскивать Python и зависимости программы с собой на другой компьютер, давайте объединим все в один исполняемый файл. Это делается с помощью PyInstaller, который устанавливается с помощью простой команды pip install pyinstaller.

Пе­рехо­дим с помощью коман­дной стро­ки в пап­ку с нашей прог­раммой и собира­ем ее коман­дой

Аргумент —onefile заставит PyInstaller упаковать все в один файл. После -i вы должны указать путь к значку исполняемого файла, если хотите его использовать. Если он вам не нужен, просто удалите этот аргумент. Последнее — это путь к файлу с нашим кодом. Если вы не хотите, чтобы консоль появлялась при запуске (например, если владелец компьютера не знает, что вы собираетесь ему помочь: D), измените расширение входного файла с помощью кода на .pyw или укажите параметр -w.

Результат сканирования на VirusTotal

Ре­зуль­тат ска­ниро­вания на VirusTotal

Пол­ный код про­екта я раз­местил на GitHub. Там есть и прог­рамма‑сбор­щик, о которой я рас­ска­жу ниже.

Сборщик с графическим интерфейсом

Для соз­дания GUI сбор­щика нам при­дет­ся работать с биб­лиоте­кой Tkinter, поэто­му преж­де все­го импорти­руем ее и нуж­ные эле­мен­ты:

Пос­ле это­го нуж­но соз­дать окно, которое и будет осно­вой интерфей­са:

Нам нужен толь­ко ввод API-клю­ча для дос­тупа к боту. Дела­ется такой ввод кодом ниже:

Это соз­даст два гра­фичес­ких объ­екта — поле вво­да и под­пись к нему.

В этом интерфей­се не хва­тает кноп­ки для сбор­ки выход­ного фай­ла. Давай соз­дадим ее:

button = Button ( root , text = "Create" , command = clicked , height = 2 , width = 10 )

Соз­даем фун­кцию, которая дол­жна находить­ся в фай­ле пос­ле импорта биб­лиотек. В ней мы дол­жны соз­давать файл и записы­вать в него код полез­ной наг­рузки.

Различная информацию об операционной системе и языке Python.

Python часто используется в качестве кроссплатформенного языка и иногда необходимо знать, на какой системе работает программа.

Например, инструмент для управления сетевой конфигурацией операционной системы может определять переносимое представление сетевых интерфейсов, псевдонимов, IP-адресов и т. д., но когда приходит время редактировать файлы конфигурации, то Python должен знать больше о хосте, чтобы использовать правильные команды и файлы конфигурации операционной системы.

Модуль platform включает в себя инструменты для получения сведений об аппаратной платформе, операционной системе и интерпретаторе на которой выполняется программа.

Содержание:

    Кроссплатформенные функции:
      platform.architecture() , platform.machine() , platform.node() , platform.platform() , platform.processor() , platform.python_build() , platform.python_compiler() , platform.python_branch() , platform.python_implementation() , platform.python_revision() , platform.python_version() , platform.python_version_tuple() , platform.release() , platform.system() , , platform.version() , platform.uname() ,
      platform.java_ver() ,
      platform.win32_ver() , platform.win32_edition() , platform.win32_is_iot() ,
      platform.mac_ver() ,
      platform.libc_ver() ,
      platform.freedesktop_os_release() (доступна в Python 3.10).

    Кроссплатформенные функции.

    Функция platform.architecture() запрашивает исполняемый файл executable для получения различной информации об архитектуре. По умолчанию двоичный файл интерпретатора Python.

    Возвращает кортеж (bits, linkage), который содержит информацию об архитектуре битов и формате связи, используемом для исполняемого файла. Оба значения возвращаются в виде строк.

    Функция полагается на системную команду file для выполнения реальной работы. Это доступно на большинстве, если не на всех платформах Unix и некоторых не-Unix платформах и только в том случае, если исполняемый файл указывает на интерпретатор Python.

    Примечание.
    В Mac OS X (и, возможно, на других платформах) исполняемые файлы могут быть универсальными файлами с несколькими архитектурами. Чтобы получить 64-разрядность текущего интерпретатора, более надежно запросить атрибут sys.maxsize :

    platform.machine() :

    platform.node() :

    Функция platform.node() возвращает сетевое имя компьютера, может быть не полностью! Если значение не может быть определено, то возвращается пустая строка..

    platform.platform(aliased=0, terse=0) :

    Функция platform.platform() возвращает одну строку, идентифицирующую базовую платформу, с максимально возможным количеством полезной информации.

    Вывод предназначен для чтения человеком, а не для машинного анализа. Это может выглядеть по-разному на разных платформах, и это предназначено.

    Если aliased имеет значение True , функция будет использовать псевдонимы для различных платформ, которые сообщают имена систем, которые отличаются от их общих имен, например SunOS будет сообщаться как Solaris.

    При установке значения terse в значение True функция возвращает только абсолютный минимум информации, необходимой для идентификации платформы.

    platform.processor() :

    Возвращается пустая строка, если значение не может быть определено. Обратите внимание, что многие платформы не предоставляют эту информацию или просто возвращают то же значение, что и для platform.machine() .

    platform.python_build() :

    Функция platform.python_build() возвращает кортеж (buildno, builddate) с указанием номера и даты сборки Python в виде строк.

    platform.python_compiler() :

    Функция platform.python_compiler() возвращает строку, идентифицирующую компилятор, используемый для компиляции Python.

    platform.python_branch() :

    Функция platform.python_branch() возвращает строку, идентифицирующую ветвь SCM реализации Python.

    platform.python_implementation() :

    Функция platform.python_implementation() возвращает строку, идентифицирующую реализацию Python. Возможные возвращаемые значения: ‘CPython’ , ‘IronPython’ , ‘Jython’ , ‘PyPy’ .

    platform.python_revision() :

    Функция platform.python_revision() возвращает строку, идентифицирующую ревизию SCM реализации Python.

    platform.python_version() :

    Обратите внимание, что в отличие от Python sys.version() , возвращаемое значение всегда будет включать уровень исправления (по умолчанию 0).

    platform.python_version_tuple() :

    Функция platform.python_version_tuple() возвращает версию Python как кортеж (major, minor, patchlevel) строк.

    Обратите внимание, что в отличие от Python sys.version, возвращаемое значение всегда будет включать уровень исправления (по умолчанию он равен 0).

    platform.release() :

    platform.system() :

    platform.system_alias(system, release, version) :

    Функция platform.system_alias() возвращает (system, release, version) , связанные с общими маркетинговыми именами, используемыми в некоторых системах.

    platform.version() :

    platform.uname() :

    Функция platform.uname() представляет портативный интерфейс команды uname. Возвращает именованный кортеж, содержащий шесть атрибутов: system , node , release , version , machine и processor .

    Обратите внимание, что функция platform.uname() добавляет шестой атрибут ( processor ), отсутствующий в результате os.uname(). Кроме того, имена атрибутов отличаются для первых двух атрибутов. Функция оs.uname() называет их sysname и nodename .

    Функции платформы Java

    Функция platform.java_ver() возвращает версию интерфейса для Jython.

    Функции платформы Windows

    Функция platform.win32_ver() получает дополнительную информацию о версии из реестра Windows и возвращает кортеж (release, version, csd, ptype) , относящийся к выпуску ОС, номеру версии, уровню CSD (пакет обновления) и типу ОС (многопроцессорный/однопроцессорный).

    Примечание. Эта функция лучше всего работает с установленным пакетом win32all Марка Хаммонда. Очевидно, что функция platform.win32_ver() работает только на Win32-совместимых платформах.

    platform.win32_edition() :

    platform.win32_is_iot() :

    Функция platform.win32_is_iot() возвращает True , если версия Windows, возвращенная platform.win32_edition() , распознается как версия IoT .

    Функции платформы Mac OS.

    Функция platform.mac_ver() Получите информацию о версии Mac OS и возвращает ее как кортеж (release, versioninfo, machine) , а versioninfo так-же является кортежем (version, dev_stage, non_release_version) .

    Функции платформы Unix.

    Функция platform.libc_ver() пытается определить версию libc , с которой связан исполняемый файл, по умолчанию интерпретатор Python.

    Возвращает кортеж строк (lib, version) , которые по умолчанию соответствуют заданным параметрам в случае сбоя поиска.

    Обратите внимание, что эта функция хорошо знает, как разные версии libc добавляют символы к исполняемому файлу. Можно использовать только для исполняемых файлов, скомпилированных с использованием gcc .

    Файл читается и сканируется кусками байтов.

    Функции платформы Unix.

    platform.freedesktop_os_release() :

    Вызывает ошибку OSError или подкласс OSError , если невозможно прочитать ни /etc/os-release , ни /usr/lib/os-release .

    В случае успеха функция возвращает словарь, в котором ключи и значения являются строками. В значениях есть специальные символы, такие как " и $ без кавычек. Поля NAME , ID и PRETTY_NAME всегда определяются в соответствии со стандартом. Все остальные поля являются необязательными. Поставщики могут включать дополнительные поля.

    Обратите внимание, что такие поля, как NAME , VERSION и VARIANT , представляют собой строки, подходящие для представления пользователям. Программы должны использовать такие поля, как ID , ID_LIKE , VERSION_ID или VARIANT_ID для идентификации дистрибутивов Linux.

    Что мне нужно посмотреть, чтобы увидеть, нахожусь ли я на Windows или Unix и т. Д.?

    platform.system() выглядит следующим образом:

    • Linux: Linux
    • Mac: Darwin
    • Windows: Windows

    Я использую инструмент WLST, который поставляется с weblogic, и он не реализует пакет платформы.

    Помимо исправлений системы javaos.py (проблема с os.system () в Windows 2003 с jdk1.5) (что я не могу сделать, я должен использовать weblogic из коробки), вот что я использую:

    Вы также можете использовать sys.platform , если вы уже импортировали sys и вы не хотите импортировать другой модуль

    Как насчет простой реализации Enum, подобной следующей? Нет необходимости во внешних библиотеках!

    Просто вы можете получить доступ с помощью значения Enum

    Это решение работает как для python , так и для jython .

    Используйте как это:

    Пример кода для разграничения ОС, использующих python:

    Как насчет нового ответа:

    Это был бы вывод, если бы я использовал MACOS

    Вы можете посмотреть код в pyOSinfo . является частью пакета pip-date , чтобы получить наиболее актуальную информацию об ОС, как видно из вашего дистрибутива Python.

    Одна из наиболее распространенных причин, по которой люди хотят проверить свою ОС, - совместимость терминала и наличие определенных системных команд. К сожалению, успех этой проверки в некоторой степени зависит от вашей установки на Python и ОС. Например, uname недоступно в большинстве пакетов Python для Windows. Приведенная выше программа на python покажет вывод наиболее часто используемых встроенных функций, уже предоставленных os, sys, platform, site .

    enter image description here

    Таким образом, лучший способ получить только необходимый код - посмотреть на that в качестве примера. (Думаю, я мог бы просто вставить это сюда, но это не было бы политкорректно.)

    Если вы работаете в MacOS X и запускаете platform.system() , вы получаете дарвина потому что macOS X построен на Apple Darwin OS. Darwin является ядром macOS X и по сути является macOS X без графического интерфейса.

    Будьте осторожны, если вы используете Windows с Cygwin, где os.name равен posix .

    Я начал более систематический список значений, которые вы можете ожидать, используя различные модули (не стесняйтесь редактировать и добавлять свою систему):

    • пробовал с archlinux и mint, получил те же результаты
    • на python2 sys.platform содержит суффикс версии ядра, например linux2 , все остальное остается идентичным
    • тот же вывод в подсистеме Windows для Linux (пробовал с Ubuntu 18.04 LTS), за исключением platform.architecture() = ('64bit', 'ELF')

    (с 32-битным столбцом в 32-битной подсистеме)

    • также существует distutils.util.get_platform() , идентичный `sysconfig.get_platform
    • Анаконда на Windows такая же, как официальный установщик Python для Windows
    • У меня нет ни Mac, ни настоящей 32-битной системы, и я не был мотивирован сделать это онлайн

    Чтобы сравнить с вашей системой, просто запустите этот скрипт (и, пожалуйста, добавьте результаты здесь, если отсутствует :)

    Для записи вот результаты на Mac:

    Короткая история

    Используйте platform.system() . Возвращает Windows , Linux или Darwin (для OSX).

    Длинная история

    Есть 3 способа получить ОС в Python, каждый со своими плюсами и минусами:

    Метод 1

    Как это работает (источник OS): Internally API для получения имени ОС в соответствии с определением ОС. См. здесь для различных значений, специфичных для ОС.

    Pro: Нет магии, низкий уровень.

    Против: зависит от версии ОС, поэтому лучше не использовать напрямую.

    Метод 2

    Как это работает (источник): внутренняя проверка Python имеет OS-специфичные модули, называемые posix или nt.

    Pro: просто проверить, работает ли posix OS

    Против: нет различий между Linux и OSX.

    Метод 3

    Как это работает (источник): внутренне это в конечном итоге будет вызовите внутренние API-интерфейсы ОС, получите имя для конкретной версии ОС, такое как «win32» или «win16» или «linux1», а затем нормализуйте до более общих имен, таких как «Windows», «Linux» или «Darwin», применяя несколько эвристик.

    Pro: Лучший портативный способ для Windows, OSX и Linux.

    Против: Python люди должны поддерживать эвристику нормализации в актуальном состоянии.

    • Если вы хотите проверить, является ли ОС Windows, Linux или OSX, то самый надежный способ - platform.system() .
    • Если вы хотите делать вызовы для конкретной ОС, но через встроенные модули Python posix или nt , используйте os.name .
    • Если вы хотите получить необработанное имя ОС, как указано самой ОС, используйте sys.platform .

    Если вы хотите, чтобы данные читались пользователем, но все еще были подробными, вы можете использовать platform.platform ()

    Вот несколько возможных звонков, которые вы можете сделать, чтобы определить, где вы находитесь

    Сервер Ubuntu 12.04, например, дает:

    Интересные результаты на Windows 8:

    Изменить . Это ошибка.

    Я опаздываю к игре, но, на всякий случай, кому-то это нужно, эту функцию я использую для корректировки своего кода, чтобы он работал на Windows, Linux и MacO:

    Для Jython единственный способ получить имя ОС, которое я нашел, - это проверить свойство os.name Java (пробовал с модулями sys , os и platform для Jython 2.5.3 в WinXP) :

    И вы можете сделать это:

    Если вы не ищете версию ядра и т. Д., Но ищете дистрибутив Linux, вы можете использовать следующее

    Очевидно, это будет работать, только если вы запускаете это на Linux. Если вы хотите иметь более общий сценарий на разных платформах, вы можете смешать его с примерами кода, приведенными в других ответах.

    Вы также можете использовать только модуль платформы без импорта модуля OS для получения всей информации.

    Хорошая и аккуратная компоновка для целей отчетности может быть достигнута с помощью этой строки:

    Это дает такой вывод:

    Чего обычно не хватает, так это версии операционной системы, но вы должны знать, используете ли вы windows, linux или mac, независимый от платформы способ использовать этот тест:

    Черт - Бренди победил меня, но это не значит, что я не могу предоставить вам результаты системы для Vista!

    . и я не могу поверить, что никто еще не опубликовал для Windows 10:

    Я знаю, что это старый вопрос, но я полагаю, что мой ответ может быть полезен для некоторых людей, которые ищут простой и понятный способ понимания ОС в своем коде. Проверено на python3.7

    Проверьте доступные тесты с модульной платформой и распечатайте ответ для вашей системы:

    Чтото гугл не помог. Задача в следующем: скриптом нужно определить тип и версию операционной системы и в зависимости от того в какой операционной системе запущен скрипт, выполнить соответствующий код допустимый в данной ОС. Питон 2.6.5.

    Отредактировано (Июль 9, 2010 14:59:27)

    Автоматическое определение ОС.

    Автоматическое определение ОС.

    Автоматическое определение ОС.

    Автоматическое определение ОС.

    По-моему get_platform возвращает то же самое, что и sys.platform. При этом разрядность системы вряд ли удастся определить, т.к. даже на х64 этот метод возвращает win32, видимо, из-за того, что интерпретатор работаем в x86 режиме.

    Кстати, есть еще один способ:

    В этом случае можно получить название ос без лишних подробностей, т.е. “Windows” или “Linux”.

    Автоматическое определение ОС.

    я использовал platform.architecture()
    разрядность определяется на ура.
    Для моей убунты это ('64bit', ‘ELF’)
    Что было на XP и Vista - не помню, но 64bit/32bit присутствовало. Использовал это для создания платформозависимых оберток на ctypes.
    sys.platform/platform.system() определяют семейство операционной системы - ‘linux2’ и ‘Linux’ в моем случае соответственно.

    'win32' вносит некоторую путаницу, но это собирательное название для Microsoft Windows начиная с Windows 95 - безотносительно к архитектуре процессора, на котором исполняется код. Т.е. даже Windows Mobile на ARM покажет ‘win32’, если ничего не путаю.

    Автоматическое определение ОС.

    Насчет win32 вы правы, я и не говорил, что ожидал чего-то в духе “win64”, я предпологал, что на x64 увижу что-то вроде “win32-x64”.
    Кстати, модуль platform на Win7 x64 работает вот так:

    Отредактировано (Июль 10, 2010 17:43:48)

    Автоматическое определение ОС.

    надо полагать, у вас все же 32 битный питон, работающий в Wow64.
    platform.architecture возвращает архитектуру для вызвавшего его процесса.
    Для винды я бы вызывал GetVersionEx/GetSystemInfo/GetNativeSystemInfo через ctypes

    Автоматическое определение ОС.

    Андрей Светлов
    надо полагать, у вас все же 32 битный питон, работающий в Wow64.

    Так и есть, я об этом писал выше.

    Отредактировано (Июль 11, 2010 02:00:58)

    Автоматическое определение ОС.

    за информацию о 2.7/3.2 спасибо, не знал.
    Только какое-то немного сомнительное решение.
    Рассмотрим такую ситуацию: мне нужно подключать разные dll в зависимости от используемой архитектуры.
    В старом подходе все было ясно. Теперь же прийдется делать какую-то другую проверку. Ведь если у меня 32 битный питон, то уже не столь важно, какая разрядность у самой винды - будут работать только 32 битные расширения и точка.

    К переменным окружения отношусь несколько настороженно. При запуске дочернего процесса они, конечно, наследуются по умолчанию. Но вместе с тем запускающий процесс может установить их как душа пожелает или вообще сбросить. Получится, что ваш код имеет шанс неправильно отработать только из-за того, что криворукий программист сделал несовсем корректную заускалку. Выяснение проблемы может быть непростым, а все что вы услышите будет звучать как “программа ххх не работает, если я вызываю ее через subprocess”. Поверьте, я такое не раз видел.

    Читайте также: