Хороший стиль для вызова команд bash в Python script с помощью os.system( "bash code" )?

Мне было интересно, считается ли это хорошим стилем для вызова команд bash в Python script с помощью os.system(). Мне также было интересно, безопасно ли это делать.

Я знаю, как реализовать некоторые функции, которые мне нужны в bash и в Python, но гораздо проще и интуитивно реализовать его в Bash. Тем не менее, я чувствую, что очень тяжело писать os.system( "bash code" ).

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

В bash: * mv.ext/path/to/destination В Python (Pseudocode):  для файла в каталоге:   if file.endswith( "ext" ):       переместить файл в пункт назначения

В этом случае, что мне делать?

Ответ 1

Прежде всего, ваш пример использует mv, который является программой в coreutils, а не bash.

Использование вызовов os.system() для внешних программ считается неудовлетворительным, потому что:

  • Вы создаете зависимости от платформы
  • Вы создаете зависимости, зависящие от версии (да, даже иногда ядро ​​меняются!)
  • Вам нужно проверить наличие внешних команд (и что они находятся в $PATH и исполняются пользователем и т.д.).
  • Вам нужно обернуть команды с проверкой ошибок, используя их код возврата. Гораздо лучше использовать коды ошибок или исключения на языке. (os.system() не позволяет вам разобрать stdout/stderr)
  • Вам приходится иметь дело с цитированием переменных с пробелами самостоятельно (или с их помощью)
  • Python уже выполнил эту работу, предоставив библиотеки!

Найдите glob, для сопоставления шаблонов (globbing) и shutil, как уже упоминалось в других. В противном случае все, что вам нужно, уже находится в стандартных библиотеках.

import glob
import shutil

for extfile in glob.glob('*.ext'):
    shutil.move(extfile,dest)  

Кроме того, os.system() не следует использовать - вместо этого посмотрите на подпроцесс.

Ответ 2

Откроется модуль Python shutil. Он предлагает операции с файловой системой, такие как перемещение файлов. Между этим и модулем os вы должны иметь все необходимые инструменты. Это предпочтительнее для команд bash по другим причинам.

Ответ 3

Всегда лучше и лучше использовать функции Python для создания такого рода вещей. С Python не так сложно написать script не зависящим от ОС образом, а не с помощью bash.

Ответ 4

Некоторые причины, по которым вы должны использовать чистый Python,

  • Используя Python, вы уже сделали предположение, что установлены Python и стандартные библиотеки. Используя код Bash внутри Python, вы делаете это предположение плюс предположение, что Bash установлен и на пути к системе.
  • Используя комбинацию из двух языков, вы делаете код более сложным для чтения другими (не все знают Python и Bash)
  • Если вы сделаете это способом Python, он будет чувствовать себя более естественным до того, как более длинные строки кода не всегда будут лучше.

В этом случае я бы использовал...

import os
for filename in os.listdir('.'):
  if filename.endswith('.ext'):
    os.rename(filename, os.path.join('path', 'to', 'new', 'destination', filename))

Там могут быть лучшие способы, но

Ответ 5

Это не идея, поскольку она делает ваш script a лот менее портативным. Нативный python script может работать на любой машине unix или Windows, на которой установлены соответствующие библиотеки python. Когда вы добавляете команды оболочки в микс, вы нарушаете это и внезапно блокируетесь до гораздо более узкого подмножества.

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

Ответ 6

Только цитирующие проблемы говорят о том, что предпочтительным является чистое решение Python.

Ответ 7

В более общем плане Python предоставляет модуль "subprocess", который позволит вам запускать команды и осуществлять большой контроль над их выходом. Он позволяет вам "создавать новые процессы, подключаться к их каналам ввода/вывода/ошибок и получать их коды возврата":

http://docs.python.org/library/subprocess.html