- Python | Execute and parse Linux commands
- Subprocess –
- Starting a process –
- Listing the directories –
- Выполнение shell команд с Python
- Использование os.system для запуска команды
- Выполнение команды с подпроцессом
- Выполнение команды с Popen
- Какой из них я должен использовать?
- Python Execute Unix / Linux Command Examples
- os.system example (deprecated)
- Say hello to subprocess
- Related media
Python | Execute and parse Linux commands
Linux is one of the most popular operating systems and is a common choice for developers. It is popular because it is open source, it’s free and customizable, it is very robust and adaptable.
Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.
To begin with, your interview preparations Enhance your Data Structures concepts with the Python DS Course. And to begin with your Machine Learning Journey, join the Machine Learning — Basic Level Course
An operating system mainly consists of two parts: The kernel and the Shell. The kernel basically handles communication between the software and the hardware. The shell takes inputs or commands from the user and produces an output. Most Linux distributions nowadays use the BASH shell (Bourne again shell). Shell commands and scripts are very powerful and are used commonly by developers.
In this article, we shall look at executing and parsing Linux commands using python.
Subprocess –
Subprocess is a module in Python that allows us to start new applications or processes in Python. This module intends to replace several older modules in python. We can use this module to run other programs or execute Linux commands.
Starting a process –
A new process can be spawned by using the Popen function defined in the subprocess module. It is a constructor for the Popen class that takes arguments to set up the new process. The underlying process creation and management in this module is handled by the Popen class.
Arguments:
- The first parameter is a list that contains the commands and their options if any.
ex: [‘ls’, ‘-l’]
the above example is equivalent to typing ‘ls -l’ in the terminal- The second parameter is the stdout value. it specifies the standard output.
ex: stdout = subprocess.PIPE
This indicates that a new pipe or redirection should be created. The default value is
“None”, which means that no redirection will occur.
We can retrieve the output of a command by using the communicate function. It reads data from stdout and stderr until it reaches the end-of-file and waits for the process to terminate. It returns a tuple that contains the output data and the error if any.
Syntax:
The output of the executed command is stored in data. Using these functions, we can execute Linux commands and fetch their output.
Listing the directories –
We can use the ‘ls’ command with options such as ‘-l’, ‘-al’, etc to list all the files in the current directory. We can then parse this output and print it in a presentable format. The get_permissions() function parses the output of the list command and retrieves only the names of the files and their corresponding permissions.
Источник
Выполнение shell команд с Python
Повторяющиеся задачи созрели для автоматизации. Разработчики и системные администраторы обычно автоматизируют рутинные задачи, такие как проверки работоспособности и резервное копирование файлов, с помощью сценариев оболочки. Однако, поскольку эти задачи становятся более сложными, сценарии оболочки могут усложняться в обслуживании.
К счастью, мы можем использовать Python вместо сценариев оболочки для автоматизации. Python предоставляет методы для запуска команд оболочки, предоставляя нам ту же функциональность, что и сценарии оболочки. Изучение того, как выполнять команды оболочки в Python, открывает нам возможность автоматизировать компьютерные задачи структурированным и масштабируемым образом.
В этой статье мы рассмотрим различные способы выполнения команд оболочки в Python и идеальную ситуацию для использования каждого метода.
Использование os.system для запуска команды
Python позволяет нам немедленно выполнить команду оболочки, которая хранится в строке, используя функцию os.system() .
Давайте начнем с создания нового файла Python с именем echo_adelle.py и введите следующее:
Первое, что мы делаем в нашем Python файле, это импортируем модуль os , который содержит функцию system , которая может выполнять команды оболочки. Следующая строка делает именно это, запускает команду echo в нашей оболочке через Python.
В вашем терминале запустите этот файл с помощью следующей команды, и вы должны увидеть соответствующий вывод:
По мере того, как команды echo выводятся в наш stdout , os.system() также возвращает код завершения команды оболочки. Код 0 означает, что он работает без проблем, а любое другое число означает ошибку.
Давайте создадим новый файл с именем cd_return_codes.py и введите следующее:
В этом сценарии мы создаем две переменные, в которых хранятся результаты выполнения команд, которые изменяют каталог на домашнюю папку и на несуществующую папку. Запустив этот файл, мы увидим:
Первая команда, которая изменяет каталог на домашний каталог, выполняется успешно. Следовательно, os.system() возвращает код ноль, который хранится в home_dir . С другой стороны, unknown_dir сохраняет код завершения неудачной команды bash, чтобы изменить каталог на несуществующую папку.
Функция os.system() выполняет команду, печатает любой вывод команды на консоль и возвращает код завершения команды. Если нам нужно более детальное управление вводом и выводом команды оболочки в Python, мы должны использовать модуль subprocess .
Выполнение команды с подпроцессом
Модуль subprocess — это рекомендуемый Python способ выполнения команд оболочки. Это дает нам гибкость для подавления вывода команд оболочки или цепочки входов и выходов различных команд вместе, в то же время обеспечивая аналогичный опыт os.system() для базовых сценариев использования.
В новом файле с именем list_subprocess.py напишите следующий код:
В первой строке мы импортируем модуль subprocess , который является частью стандартной библиотеки Python. Затем мы используем функцию subprocess.run() для выполнения команды. Также как и команда os.system() , subprocess.run() возвращает код того, что было выполнено.
Обратите внимание, что subprocess.run() принимает список строк в качестве входных данных вместо одной строки. Первым элементом списка является название команды. Остальные пункты списка — это флаги и аргументы команды.
Примечание: Как правило, вам нужно отделить аргументы , основанные на пространстве, например , ls -alh будет [«ls», «-alh»] , а ls -a -l -h , превратится в [«ls», «-a», -«l», «-h»] .
Запустите этот файл, и вывод вашей консоли будет похож на:
Теперь давайте попробуем использовать одну из более продвинутых функций subprocess.run() , а именно игнорирование вывода в stdout . В том же файле list_subprocess.py измените:
Стандартный вывод команды теперь передается на специальное устройство /dev/null , что означает, что вывод не будет отображаться на наших консолях. Запустите файл в вашей оболочке, чтобы увидеть следующий вывод:
Что если мы хотим получить результат команды? subprocess.run() поможет сделать это. Создайте новый файл с именем cat_subprocess.py , набрав следующее:
Мы используем довольно много параметров, давайте рассмотрим их:
- 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() дает нам огромную гибкость. Эта функция представляет собой упрощенную абстракцию класса 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 когда они установлены.
Мы рассмотрели три способа запуска команд оболочки в Python с использованием класса subprocess.Popen . Давайте еще раз рассмотрим их характеристики, чтобы узнать, какой метод лучше всего подходит для требований проекта.
Какой из них я должен использовать?
Если вам нужно выполнить одну или несколько простых команд и вам не помешает, если их вывод поступит в консоль, вы можете использовать команду os.system() . Если вы хотите управлять вводом и выводом команды оболочки, используйте subsystem.run() . Если вы хотите выполнить команду и продолжить выполнять другую работу, пока она выполняется, используйте subprocess.Popen .
Вот таблица с некоторыми различиями в юзабилити, которые вы также можете использовать для обоснования своего решения:
Источник
Python Execute Unix / Linux Command Examples
H ow do I execute standard Unix or Linux shell commands using Python? Is there a command to invoke Unix commands using Python programs?
Tutorial details | |
---|---|
Difficulty level | Easy |
Root privileges | No |
Requirements | Python |
Est. reading time | N/A |
You can execute the command in a subshell using os.system() . This will call the Standard C function system(). This function will return the exit status of the process or command. This method is considered as old and not recommended, but presented here for historical reasons only. The subprocess module is recommended and it provides more powerful facilities for running command and retrieving their results.
os.system example (deprecated)
In this example, execute the date command:
In this example, execute the date command using os.popen() and store its output to the variable called now:
Say hello to subprocess
The os.system has many problems and subprocess is a much better way to executing unix command. The syntax is:
In this example, execute the date command:
You can pass the argument using the following syntax i.e run ls -l /etc/resolv.conf command:
Another example (passing command line args):
In this example, run ping command and display back its output:
The only problem with above code is that output, err = p.communicate() will block next statement till ping is completed i.e. you will not get real time output from the ping command. So you can use the following code to get real time output:
Related media
A quick video demo of above python code:
References:
🐧 Get the latest tutorials on Linux, Open Source & DevOps via
Category | List of Unix and Linux commands |
---|---|
Documentation | help • mandb • man • pinfo |
Disk space analyzers | df • duf • ncdu • pydf |
File Management | cat • cp • less • mkdir • more • tree |
Firewall | Alpine Awall • CentOS 8 • OpenSUSE • RHEL 8 • Ubuntu 16.04 • Ubuntu 18.04 • Ubuntu 20.04 |
Linux Desktop Apps | Skype • Spotify • VLC 3 |
Modern utilities | bat • exa |
Network Utilities | NetHogs • dig • host • ip • nmap |
OpenVPN | CentOS 7 • CentOS 8 • Debian 10 • Debian 8/9 • Ubuntu 18.04 • Ubuntu 20.04 |
Package Manager | apk • apt |
Processes Management | bg • chroot • cron • disown • fg • glances • gtop • jobs • killall • kill • pidof • pstree • pwdx • time • vtop |
Searching | ag • grep • whereis • which |
Shell builtins | compgen • echo • printf |
Text processing | cut • rev |
User Information | groups • id • lastcomm • last • lid/libuser-lid • logname • members • users • whoami • who • w |
WireGuard VPN | Alpine • CentOS 8 • Debian 10 • Firewall • Ubuntu 20.04 |
Comments on this entry are closed.
307 ms?
That’s a long interval 😉
Hi, please more small and usefull examples with python like it! more code snippets!
A very comprehensive explanation, being useful to beginners to python.
where to find the command of linux
these commands are very helpfull us….please give more example like this.
What exactly does Shell=True does?
please tell the exact usage of the shell argumet.
First off, enjoy all your posts and youtube videos. Recently viewed your tutorial on installing freebsd. So thank you for sharing your knowledge.
I have a query regarding launching an external bash script file (.sh) in freebsd.
For linux I used:
os.system(‘sh ‘ + filepath)
For Mac:
os.system(‘open ‘ + filepath)
And for windows:
os.startfile(filepath)
I am unable to get any of these to work for freebsd. I know startfile is only for windows, however was wondering if there was an equivalent for freebsd without using subprocess. Or if not possible at all how to use subprocess to call a external script.
Also, in freebsd, what would be the equivalent of say:
sudo chown -R user:user file.bundle
as both sudo and chown are not installed by default.
Any help would be appreciated.
What if I want to create a variable in Python, then pass that variable to a bash command line?
Something like this:
….
celsius = sensor.read_temperature()
import subprocess
subprocess.call([“myscript.sh”, “-v”, “-t $celsius”])
Is that possible?
Of course you can. In python’s new formatting it would look like this:
subprocess.call([«myscript.sh», «-v», «-t <>«.format(celsius)])
I use split so I dont have to write literal arrays. Works most of the time.
Источник