Rukovodstvo
статьи и идеи для разработчиков программного обеспечения и веб-разработчиков.
Выполнение команд оболочки с помощью Python
Введение Повторяющиеся задачи созрели для автоматизации. Разработчики и системные администраторы обычно автоматизируют рутинные задачи, такие как проверки работоспособности и резервное копирование файлов, с помощью сценариев оболочки. Однако по мере того, как эти задачи становятся более сложными, сценарии оболочки может становиться все труднее поддерживать. К счастью, мы можем использовать Python вместо сценариев оболочки для автоматизации. Python предоставляет методы для запуска команд оболочки, предоставляя нам те же функции, что и сценарии оболочки. Изучение того, как запускать команды оболочки в Pyt
Время чтения: 7 мин.
Вступление
Повторяющиеся задачи созрели для автоматизации. Разработчики и системные администраторы обычно автоматизируют рутинные задачи, такие как проверки работоспособности и резервное копирование файлов, с помощью сценариев оболочки. Однако по мере того, как эти задачи становятся более сложными, сценарии оболочки может становиться все труднее поддерживать.
К счастью, мы можем использовать Python вместо сценариев оболочки для автоматизации. Python предоставляет методы для запуска команд оболочки, предоставляя нам те же функции, что и сценарии оболочки. Изучение того, как запускать команды оболочки в Python, открывает нам возможность автоматизировать компьютерные задачи структурированным и масштабируемым образом.
В этой статье мы рассмотрим различные способы выполнения команд оболочки в Python и идеальную ситуацию для использования каждого метода.
Использование os.system для запуска команды
Python позволяет нам немедленно выполнить команду оболочки, которая хранится в строке, с помощью функции os.system() .
Начнем с создания нового файла Python с именем echo_adelle.py и введем следующее:
Первое, что мы делаем в нашем файле Python, — это импортируем os , который содержит system функцию, которая может выполнять команды оболочки. Следующая строка делает именно это, запускает команду echo в нашей оболочке через Python.
В вашем терминале запустите этот файл с помощью следующей команды, и вы должны увидеть соответствующий вывод:
По мере того как echo команд отпечатков на наш stdout , os.system() также отображает выходной сигнал на наш stdout потока. os.system() не отображается в консоли, она возвращает код выхода команды оболочки. Код выхода 0 означает, что он работал без проблем, а любое другое число означает ошибку.
Давайте создадим новый файл cd_return_codes.py и введем следующее:
В этом сценарии мы создаем две переменные, в которых хранится результат выполнения команд, которые меняют каталог на домашнюю папку и на несуществующую папку. Запустив этот файл, мы увидим:
Первая команда, которая меняет каталог на домашний каталог, выполняется успешно. Следовательно, os.system() возвращает нулевой код выхода, который хранится в home_dir . С другой стороны, unknown_dir хранит код выхода неудачной команды bash для изменения каталога на несуществующую папку.
Функция os.system() выполняет команду, выводит любой вывод команды на консоль и возвращает код выхода команды. Если мы хотим более детального управления вводом и выводом команд оболочки в Python, мы должны использовать модуль subprocess
Запуск команды с подпроцессом
- это рекомендуемый Python способ выполнения команд оболочки. Это дает нам гибкость для подавления вывода команд оболочки или цепочки входов и выходов различных команд вместе, при этом обеспечивая аналогичный опыт с os.system() для базовых случаев использования.
В новом list_subprocess.py именем list_subprocess.py напишите следующий код:
В первой строке мы импортируем subprocess , который является частью стандартной библиотеки Python. Затем мы используем subprocess.run() для выполнения команды. Как и os.system() , команда subprocess.run() возвращает код выхода того, что было выполнено.
В отличие от os.system() , обратите внимание, что subprocess.run() требует в качестве входных данных список строк, а не одну строку. Первый элемент списка — это имя команды. Остальные элементы списка — это флаги и аргументы команды.
Примечание. Как правило, аргументы необходимо разделять по ls -alh будет ["ls", "-alh"] , а ls -a -l -h будет ["ls", "-a", -"l", "-h"] . В качестве другого примера, echo hello world будет ["echo", "hello", "world"] , тогда как echo "hello world" или echo hello\ world будет ["echo", "hello world"] .
Запустите этот файл, и вывод вашей консоли будет примерно таким:
Теперь давайте попробуем использовать одну из более продвинутых функций subprocess.run() , а именно игнорировать вывод в stdout . В том же list_subprocess.py измените:
Стандартный вывод команды теперь направляется на специальное устройство /dev/null , что означает, что вывод не будет отображаться на наших консолях. Запустите файл в своей оболочке, чтобы увидеть следующий вывод:
Что, если бы мы хотели предоставить ввод для команды? subprocess.run() облегчает это своим input аргументом. Создайте новый файл с именем cat_subprocess.py , набрав следующее:
Мы используем subprocess.run() с довольно большим количеством команд, давайте рассмотрим их:
- stdout=subprocess.PIPE указывает Python перенаправить вывод команды на объект, чтобы его можно было вручную прочитать позже
- text=True возвращает stdout и stderr как строки. Тип возвращаемого значения по умолчанию — байты.
- input="Hello from the other side" указывает Python добавить строку в качестве входных данных для команды cat .
Запуск этого файла дает следующий результат:
Мы также можем вызвать Exception не проверяя возвращаемое значение вручную. В новом файле false_subprocess.py добавьте следующий код:
В вашем терминале запустите этот файл. Вы увидите следующую ошибку:
Используя check=True , мы говорим Python вызывать любые исключения при обнаружении ошибки. Поскольку мы столкнулись с ошибкой, print в последней строке не был выполнен.
Функция subprocess.run() дает нам огромную гибкость, которой не os.system() при выполнении команд оболочки. Эта функция является упрощенной абстракцией subprocess.Popen , который предоставляет дополнительные возможности, которые мы можем изучить.
Выполнение команды с помощью Popen
Класс subprocess.Popen предоставляет разработчику больше возможностей при взаимодействии с оболочкой. Однако нам нужно более подробно описывать получение результатов и ошибок.
По умолчанию subprocess.Popen не останавливает обработку программы Python, если ее команда не завершила выполнение. В новом файле с именем list_popen.py введите следующее:
Этот код эквивалентен list_subprocess.py . Он запускает команду, используя subprocess.Popen , и ожидает ее завершения перед выполнением остальной части скрипта Python.
Допустим, мы не хотим ждать, пока наша команда оболочки завершит выполнение, чтобы программа могла работать над другими вещами. Как он узнает, что команда оболочки завершила выполнение?
Метод poll() возвращает код выхода, если команда завершена, или None если она все еще выполняется. Например, если бы мы хотели проверить, list_dir а не ждать его, у нас была бы следующая строка кода:
Чтобы управлять вводом и выводом с помощью subprocess.Popen , нам нужно использовать метод communicate() .
В новый файл с именем cat_popen.py добавьте следующий фрагмент кода:
Метод communicate() принимает input аргумент, который используется для передачи входных данных команде оболочки. Метод communicate также возвращает и stdout и stderr если они установлены.
Ознакомившись с основными идеями subprocess.Popen , мы рассмотрели три способа запуска команд оболочки в Python. Давайте еще раз рассмотрим их характеристики, чтобы узнать, какой метод лучше всего подходит для требований проекта.
Какой мне использовать?
Если вам нужно запустить одну или несколько простых команд и вы не возражаете, если их вывод пойдет на консоль, вы можете использовать команду os.system() . Если вы хотите управлять вводом и выводом команды оболочки, используйте subprocess.run() . Если вы хотите запустить команду и продолжить выполнение другой работы во время ее выполнения, используйте subprocess.Popen .
Вот таблица с некоторыми различиями в удобстве использования, которую вы также можете использовать для обоснования своего решения:
Python System Command — os.system(), subprocess.call()

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
In this tutorial we will learn about Python System Command. Previously we learned about Python Random Number.
Python System Command
While making a program in python, you may need to exeucte some shell commands for your program. For example, if you use Pycharm IDE, you may notice that there is option to share your project on github. And you probably know that file transferring is done by git, which is operated using command line. So, Pycharm executes some shell commands in background to do it. However, In this tutorial we will learn some basics about executing shell commands from your python code.
Python os.system() function
We can execute system command by using os.system() function. According to the official document, it has been said that
This is implemented by calling the Standard C function system(), and has the same limitations.
However, if command generates any output, it is sent to the interpreter standard output stream. Using this command is not recommended. In the following code we will try to know the version of git using the system command git —version .
The following output found in ubuntu 16.04 where git is installed already.
Notice that we are not printing the git version command output to console, it’s being printed because console is the standard output stream here.
Python subprocess.call() Function
In the previous section, we saw that os.system() function works fine. But it’s not recommended way to execute shell commands. We will use Python subprocess module to execute system commands. We can run shell commands by using subprocess.call() function. See the following code which is equivalent to the previous code.
And the output will be same also. 
Python subprocess.check_output() function
So far, we executed the system commands with the help of python. But we could not manipulate the output produced by those commands. Using subprocess.check_output() function we can store the output in a variable.
It will produce output like the following
So, in the above sections we have discussed about basic ideas about executing python system command. But there is no limit in learning. If you wish, you can learn more about Python System command using subprocess module from official documentation.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.