21 ноября | 2024г. | 20:53:33


АвторТема: Работа с командной строкой в Linux через python  (Прочитано 9585 раз)

0 Пользователей и 1 Гость смотрят эту тему.

Оффлайн DobrodelАвтор темы

  • Друзья Джедаев
  • *****
  • Сообщений: 159
  • Поблагодарили: 259
  • Уважение: -1
Друзья здравствуйте,
Хочу поделиться своим опытом по поводу ответа на вопрос:

Как запускать команды bash (в Linux) из python?

Первый вопрос, который может возникнуть - для чего использовать другой язык, если всё (или почти всё) можно реализовать при помощи pyton?
Ответ прост - время выполнения нашего кода. Это пожалуй самый главный, решающий фактор для нас, так как мы с Вами знаем, что процессор и другие компоненты в ресивере несколько уступают по производительности настольным компьютерам. Именно поэтому я рассматриваю вариант использования bash в качестве реального инструмента при программировании для enigma2, особенно если дело касается обработки большого объёма данных, как например данных EPG.
Ну и в качестве второго аргумента приведу, что иногда на bash можно сделать более эффективно и быстрее чем на python. Например при обработке срок, используя sed.

Итак приступим к рассмотрению нашего основного вопроса:
Как Вы наверное все знаете, в python существует библиотека для этих целей под названием os
И функция os.system() выполняет всё наши команды. И в качестве результата возвратит код успешности завершённого процесса.
Однако этот вариант хорош в том случае, когда нам нет необходимости в возврате результата из командной строки.

Если же нам необходимо получить результат выполнения из командной строки, то здесь нам python даёт другой способ: функцию  Popen  из класса subprocess.
Вот об этом варианте я и хочу рассказать, чтобы в последствии Вы не сталкивались с теми же трудностями, что и я.

Итак функция работает следующим образом:
1. Формируем командную строку
2. Разбиваем ее на аргументы
3. Выполняем вызов функции Popen()
4. Забираем результат функцией communicate()[0]
5. Разбираем ошибки в communicate()[1].

Например мы хотим вывести список всех файлов в директории /etc, для этого напишем следующий код:

Вам не разрешен просмотр кода. Войдите или Зарегистрируйтесь для просмотра.
На выходе получаем список файлов в переменной listFiles разделённые символом новой строки.
Однако и этот вариант не всегда хорош.
Для примера, если мы хотим выполнить две или три команды подряд (например для фильтрации результата при помощи grep или sed), то переданный символ соединения команд «|» не будет воспринят к исполнению и выполнение завершится ошибкой.

Здесь можно выйти из положения методом разделения потоков. Создать два потока и передать одному результат выполнения другого, как здесь:

Вам не разрешен просмотр кода. Войдите или Зарегистрируйтесь для просмотра.
Однако при выполнении трех и более команд по конвейеру в bash  - получается нагромождение кода. Что делать в этом случае?

Нашёл очень простое решение, описанное в документации)). Делаем следующее:
1. Формируем командную строку
3. Выполняем вызов функцией Popen(), с обязательным аргументом shell=True
4. Забираем результат функцией communicate()[0]
5. Разбираем ошибки в communicate()[1].

Другими словами, теперь мы не разбираем строку на аргументы, а пишем ее так как писали бы её в командном интерпретаторе shell, типа bash или в нашем случае tuxbox
Вот сам код, как пример - выполним команду для получения значения аргумента из файла установок enigma2:
(конечно же существуют классы работы с конфиг файлами - здесь привожу просто как пример, не более):

Вам не разрешен просмотр кода. Войдите или Зарегистрируйтесь для просмотра.
Как видно из примера мы полняем сразу три конвейерных команды cat, grep и sed.
Таким образом получаем достаточно небольшой код и результат выполнения командной строки в нашу переменную для последующей обработки.

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

Если есть вопросы - пишите.
  • Vu Duo+ (GI S9895 HD), LiveX (ruDream), 13E, 36E
С Уважением, Добродел

Оффлайн Taapat

  • Мастер Джедай
  • ***
  • Сообщений: 3543
  • Поблагодарили: 10700
  • Уважение: +60
Я не знаю как на других имиджах, но если речь о openpli, то думаю тут к месту цитата MiLo:
Цитировать
Whatever you do, AVOID using "os.system" at any cost. It will FAIL to work, there's no real explanation why. The "popen" calls have the exact same problem. Only "Console" works.
После их использования кажется что все работает как надо, и вдруг непонятные косяки в вещах даже не связанных с применением их.
Правда он по моему говорит о popen из os, и может с subprocess таких проблем нету.
  • Zgemma H7S | Zgemma H.S | Edision OS mini + | Amiko SHD-8900 Alien | VU+ Solo2 | Gi ET11000 4K
taapat.blogspot.com

Теги:
 

Похожие темы

  Тема / Автор Ответов Последний ответ
66 Ответов
37430 Просмотров
Последний ответ 14 февраля | 2013г. | 16:54:07
от Chef70
27 Ответов
26341 Просмотров
Последний ответ 04 апреля | 2022г. | 06:06:17
от тихон
51 Ответов
87060 Просмотров
Последний ответ 23 августа | 2023г. | 20:35:49
от Evg77734
0 Ответов
3586 Просмотров
Последний ответ 07 апреля | 2014г. | 00:52:47
от 2boom
7 Ответов
6686 Просмотров
Последний ответ 12 декабря | 2015г. | 20:36:30
от Maksyuha



X

Добро пожаловать!

Мы заметили, что у Вас установлено расширение AdBlock или ему подобное. Пожалуйста добавьте наш Клуб в белый список, внесите этим посильную лепту в его развитие. Спасибо!