Выполнение команд Linux и Windows в Python

Содержание статьи
Введение
Простой пример Linux
Простой пример Windows
Обработка ошибок
Bash команда с опциями
Передача аргументов в скрипт

Введение

В этой статье вы узнаете как выполнять команды Linux и Windows из кода на Python 3.

Создайте файл subprocess_lesson.py и копируйте туда код из примеров.

Запустить файл можно командой python3 subprocess.py

Простой пример

Пример программы, которая выполняет Linux команду ls

import subprocess subprocess.run('ls')

Простой пример Windows

Пример программы, которая выполняет в Windows команду dir

import subprocess subprocess.run('dir', shell=True)

У меня пока что не работает

Bash команда с опциями

Чтобы выполнить Bash команду с опциями, например, ls - la нужно добавить shell=True

import subprocess subprocess.run('ls -la', shell=True)

У использования shell=True есть одна важная особенность: нужно особенно внимательно следить за безопастностью.

Рекомендуется использовать shell=True только если вы передаёте параметры самостоятельно.

Избежать использования shell=True можно передав команду и параметры списком:

import subprocess subprocess.run(['ls', '-la'])

Разберём subprocess более подробно

import subprocess p1 = subprocess.run(['ls', '-la']) print("p1") print(p1) print("p1.args") print(p1.args) print("p1.returncode") print(p1.returncode) print("p1.stdout") print(p1.stdout)

python3 subprocess_lesson.py

total 12 drwxrwxr-x 2 andrei andrei 4096 Nov 30 17:57 . drwxrwxr-x 3 andrei andrei 4096 Nov 30 17:57 .. -rw-rw-r-- 1 andrei andrei 195 Nov 30 16:51 subprocess_lesson.py p1 CompletedProcess(args='ls -la', returncode=0) p1.args ls -la p1.returncode 0 p1.stdout None

Чтобы не выводить результат в терминал а сохранить в переменную, нужно воспользоваться опцией capture_output=True

import subprocess p1 = subprocess.run(['ls', '-la'], capture_output=True) print(p1.stdout)

python3 subprocess_lesson.py

b'total 12\ndrwxrwxr-x 2 andrei andrei 4096 Nov 30 18:41 .\ndrwxrwxr-x 3 andrei andrei 4096 Nov 30 18:40 ..\n-rw-rw-r-- 1 andrei andrei 92 Nov 30 18:41 subprocess_lesson.py\n'

Если byte вывод вам не нравится его можно декодировать

import subprocess p1 = subprocess.run(['ls', '-la'], capture_output=True) print(p1.stdout.decode())

python3 subprocess_lesson.py

total 12 drwxrwxr-x 2 andrei andrei 4096 Nov 30 18:41 . drwxrwxr-x 3 andrei andrei 4096 Nov 30 18:40 .. -rw-rw-r-- 1 andrei andrei 101 Nov 30 18:46 subprocess_lesson.py

Или можно использовать опцию text=True

import subprocess p1 = subprocess.run(['ls', '-la'], capture_output=True, text=True) print(p1.stdout)

total 12 drwxrwxr-x 2 andrei andrei 4096 Nov 30 18:41 . drwxrwxr-x 3 andrei andrei 4096 Nov 30 18:40 .. -rw-rw-r-- 1 andrei andrei 101 Nov 30 18:46 subprocess_lesson.py

Ещё один вариант перенаправления вывода stdout=subprocess.PIPE

import subprocess p1 = subprocess.run(['ls', '-la'], stdout=subprocess.PIPE, text=True) print(p1.stdout)

python3 subprocess_lesson.py

total 12 drwxrwxr-x 2 andrei andrei 4096 Nov 30 18:41 . drwxrwxr-x 3 andrei andrei 4096 Nov 30 18:40 .. -rw-rw-r-- 1 andrei andrei 101 Nov 30 18:46 subprocess_lesson.py

Вывод в файл

import subprocess with open('output.txt', 'w') as f: p1 = subprocess.run(['ls', '-la'], stdout=f, text=True)

Обработка ошибок

Добавим заведомо неверное условие в команду. Например, пусть листинг выполняется не для текущей директории а для несуществующей.

import subprocess p1 = subprocess.run(['ls', '-la', 'not_exist'], capture_output=True, text=True) print(p1.returncode) print(p1.stderr)

2 ls: cannot access 'not_exist': No such file or directory

Обратите внимане, что Python в этом примере не выдаёт никаких ошибок

Чтобы Python информировал об ошибках во внешних командах используйте опцию check=True

import subprocess p1 = subprocess.run(['ls', '-la', 'not_exist'], capture_output=True, text=True, check=True) print(p1.returncode) print(p1.stderr)

python3 subprocess_lesson.py

Traceback (most recent call last): File "subprocess_lesson.py", line 3, in p1 = subprocess.run(['ls', '-la', 'not_exist'], capture_output=True, text=True, check=True) File "/usr/lib/python3.8/subprocess.py", line 512, in run raise CalledProcessError(retcode, process.args, subprocess.CalledProcessError: Command '['ls', '-la', 'not_exist']' returned non-zero exit status 2.

Обратите внимане, что теперь Python выдаёт ошибку, а до print(p1.returncode) и print(p1.stderr) дело уже не доходит

import subprocess p1 = subprocess.run(['ls', '-la', 'not_exist'], stderr=subprocess.DEVNULL) print(p1.stderr)

python3 subprocess_lesson.py

None

Передача аргументов в скрипт

Допустим, нужно вызвать скрипт с несколькими аргументами

import subprocess subprocess.call(['./script.sh %s %s %s' %(ip, username, test_time)], shell = True)

Ещё пример: из python скрипта вызвать sed и обрезать число строк, которое сам скрипт получает как аргумент

import subprocess LINES = int(sys.argv[1]) subprocess.call(['sed -i -e 1,%sd 2021-04-22-log.txt' %(LINES)], shell = True)

Эту задачу можно решить на читом Python решение

with open('file_with_lines.txt', 'r') as fin: data = fin.readlines()[3:] with open('file_with_lines.txt', 'w') as fout: fout.writelines(data)

Поиск по сайту

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящуюю по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: