Python – Когда это нормально использовать os.system () для выдачи общих команд Linux

Отбрасывание из другого потока, когда целесообразно использовать os.system () для выдачи команд, таких как rm -rf, cd, make, xterm, ls?

Учитывая, что есть аналоговые версии вышеуказанных команд (кроме make и xterm), я предполагаю, что использовать эти встроенные команды python безопаснее, вместо использования os.system ()

Есть предположения? Я бы хотел их услышать.

7 Solutions collect form web for “Python – Когда это нормально использовать os.system () для выдачи общих команд Linux”

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

Одна из проблем system() заключается в том, что она подразумевает знание синтаксиса и языка командной строки для синтаксического анализа и выполнения вашей командной строки. Это создает вероятность ошибки, при которой вы не правильно проверяете ввод, и оболочка может интерпретировать что-то вроде замены переменных или определения того, где аргумент начинается или заканчивается таким образом, которого вы не ожидаете. Кроме того, оболочка другого ОС может иметь разный синтаксис из вашего собственного, включая очень тонкую дивергенцию, которую вы не заметите сразу. По причинам, подобным этим, я предпочитаю использовать execve() вместо system() – вы можете напрямую передавать токены argv и не беспокоиться о чем-то посередине (неверно), анализируя ваш вход.

Другая проблема с system() (это также относится к использованию execve() ) заключается в том, что когда вы кодируете это, вы говорите: «Ищите эту программу и передавайте ей эти аргументы». Это делает несколько допущений, которые могут привести к ошибкам. Во-первых, программа существует и может быть найдена в $PATH . Возможно, в какой-то системе этого не произойдет. Во-вторых, возможно, в какой-то системе или даже в будущей версии вашей собственной ОС она будет поддерживать другой набор параметров. В этом смысле я бы избегал делать это, если вы не уверены, что система, в которой вы будете работать, будет иметь программу. (Как, может быть, вы положили программу вызова в систему, чтобы начать с нее, или способ, которым вы ее вызываете, имеет такое назначение, как POSIX.)

И наконец … Также есть успех, связанный с поиском правильной программы, созданием нового процесса, загрузкой программы и т. Д. Если вы делаете что-то простое, как mv , гораздо эффективнее использовать системный вызов напрямую.

Это лишь некоторые из причин, по которым следует избегать system() . Конечно, их больше.

Ответ Дарина – хорошее начало.

Помимо этого, речь идет о том, насколько портативным вы планируете быть. Если ваша программа будет запускаться только по разумной «стандартной» и «современной» Linux, тогда вам не придется заново изобретать колесо; если вы попытаетесь переписать make или xterm они xterm вас в белые пальто. Если это работает, и у вас нет проблем с платформой, выбивайте себя и просто используйте Python в качестве клея!

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

Ваш вопрос, кажется, состоит из двух частей. Вы упомянули вызовы, такие как «xterm», «rm -rf» и «cd».

Сторона Примечание: вы не можете вызвать 'cd' в под-оболочке. Уверен, что это был трюк.

Что касается других вещей командного уровня, которые вы, возможно, захотите сделать, например, «rm -rf SOMETHING», уже есть эквивалент python. Это отвечает на первую часть вашего вопроса. Но я подозреваю, что вы действительно спрашиваете о второй части.

Вторая часть вашего вопроса может быть перефразирована как «следует ли использовать систему () или что-то вроде модуля подпроцесса?».

У меня есть простой ответ для вас: просто скажите «НЕТ» использовать «system ()», за исключением прототипирования.

Это отлично подходит для проверки того, что что-то работает, или для этого «быстрого и грязного» сценария, но слишком много проблем с os.system ():

  1. Он разворачивает оболочку для вас – отлично, если вам нужно
  2. Он расширяет для вас дикие карты – штраф, если у вас нет
  3. Он обрабатывает перенаправление – отлично, если вы хотите, чтобы
  4. Он выгружает вывод в stderr / stdout и считывает из stdin по умолчанию
  5. Он пытается понять цитату, но это не очень хорошо (попробуйте «Cmd»> «Ofile»)
  6. Связанный с # 5, он не всегда ограничивает границы аргументов (т. Е. Аргументы с пробелами в них могут быть испорчены)

Просто скажи «нет» системе () »!

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

Я бы предположил, что вы используете только os.system для вещей, которые еще не эквивалентны для модуля os . Зачем делать вашу жизнь труднее?

В python вызов os.system начинает «нахмуриться». «Новая» замена будет subprocess.call или subprocess.Popen в модуле подпроцесса. Проверьте документы для подпроцесса

Другая приятная вещь в подпроцессе – вы можете читать stdout и stderr в переменных и обрабатывать, не переходя к другим файлам.

Как и другие, упомянутые выше, есть модули для большинства вещей. Если вы не пытаетесь приклеить много других команд, я буду придерживаться вещей, включенных в библиотеку. Если вы копируете файлы, используйте shutil, работая с архивами, у вас есть модули, такие как tarfile / zipfile и т. Д.

Удачи.

  • Связывание обратных вызовов для минимизации и максимизации событий в окнах Toplevel
  • Потерял важный .py-файл (перезаписан в виде 0-байтного файла), но старая версия все еще загружена в IPYTHON в качестве модуля - может ли она быть восстановлена?
  • Как получить выход из gdb.execute в PythonGDB (GDB 7.1)?
  • Как получить время начала процесса (или время простоя) в python
  • Python: как получить количество секунд мили за один раз
  • Какой пользователь Ansible выполнит мои команды как?
  • Что означает статус выхода 3 процесса?
  • ошибка при выполнении вызова () в подпроцессе Python
  • Обработка сигналов в python-daemon
  • Прерывание клавиатуры IPython CTRL + C несовместимо
  • Нет модуля с именем «virtualenvwrapper»
  • Python - лучший язык программирования в мире.