Python - Когда можно использовать os.system () для выдачи общих команд Linux - PullRequest
11 голосов
/ 27 июля 2010

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

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

Есть мысли? Я хотел бы услышать их.

Ответы [ 7 ]

18 голосов
/ 27 июля 2010

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

5 голосов
/ 27 июля 2010

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

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

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

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

4 голосов
/ 27 июля 2010

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

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

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

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

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

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

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

Просто скажите нет "system ()"!

4 голосов
/ 27 июля 2010

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

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

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

3 голосов
/ 27 июля 2010

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

2 голосов
/ 27 июля 2010

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

1 голос
/ 27 июля 2010

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

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

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

Удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...