import subprocess
subprocess.run(["ls", "-l"])
result = subprocess.run(["ls", "-l"], capture_output=True, text=True)
print(result.stdout)
Для выполнения более сложных команд, таких как конвейеры или перенаправления, используйте аргумент shell=True. Например, чтобы подсчитать количество строк в файле:
subprocess.run("wc -l < file.txt", shell=True)
Обратите внимание, что использование shell=True может быть небезопасным, если команда содержит пользовательский ввод. В таких случаях лучше избегать этого параметра или тщательно проверять данные.
Если вам нужно выполнить несколько команд последовательно, используйте метод Popen. Он позволяет управлять процессом более гибко. Например, чтобы запустить команду и дождаться её завершения:
process = subprocess.Popen(["sleep", "5"])
process.wait()
Для обработки ошибок добавьте аргумент check=True. Это вызовет исключение, если команда завершится с ошибкой:
subprocess.run(["ls", "/nonexistent"], check=True)
Теперь вы знаете, как выполнять Bash команды в Python. Эти методы помогут вам интегрировать внешние утилиты в ваши скрипты и автоматизировать задачи.
Выбор подходящего метода для запуска команд
- shutil.which(): Примените эту функцию, чтобы проверить доступность команды в системе перед её выполнением. Это поможет избежать ошибок, если команда отсутствует.
Если вы работаете с длительными процессами, добавьте аргумент timeout в subprocess.run(), чтобы избежать зависания. Для сложных сценариев, где требуется взаимодействие с несколькими командами, используйте subprocess.Popen() с перенаправлением потоков.
Пример:
import subprocess
result = subprocess.run(["ls", "-l"], capture_output=True, text=True)
print(result.stdout)
Для выполнения команд с повышенными привилегиями используйте sudo в сочетании с subprocess.run(), но будьте осторожны с безопасностью. Убедитесь, что команды не содержат уязвимостей для инъекций.
Использование модуля subprocess
Для выполнения Bash-команд в Python применяйте модуль subprocess. Этот модуль предоставляет гибкие инструменты для взаимодействия с системными процессами. Используйте функцию subprocess.run() для выполнения простых команд. Например, чтобы вывести список файлов в текущей директории, введите:
import subprocess
result = subprocess.run(["ls", "-l"], capture_output=True, text=True)
print(result.stdout)
Для выполнения команд с передачей данных через стандартный ввод используйте параметр input. Например, чтобы передать строку в команду grep, выполните:
result = subprocess.run(["grep", "example"], input="This is an example text", capture_output=True, text=True)
print(result.stdout)
Если нужно выполнить команду в оболочке Bash, установите параметр shell=True. Однако будьте осторожны: это может привести к уязвимостям, если команда содержит пользовательский ввод. Пример:
result = subprocess.run("echo $HOME", shell=True, capture_output=True, text=True)
print(result.stdout)
Для работы с асинхронными процессами используйте subprocess.Popen(). Этот метод позволяет запускать команды в фоновом режиме и управлять их выполнением. Например:
process = subprocess.Popen(["sleep", "5"])
process.wait()
print("Процесс завершен")
with open("output.txt", "w") as f:
subprocess.run(["ls", "-l"], stdout=f)
В таблице ниже приведены основные параметры функции subprocess.run():
| Параметр | Описание |
|---|---|
args |
Список аргументов команды или строка (при shell=True). |
capture_output |
|
text |
|
shell |
Выполняет команду через оболочку Bash. |
check |
Вызывает исключение при завершении с ошибкой. |
input |
Передает данные в стандартный ввод команды. |
С помощью subprocess вы можете интегрировать Bash-команды в Python-скрипты, что делает его мощным инструментом для автоматизации задач.
Применение os.system для простых команд
import os
os.system("touch example.txt")
Функция возвращает код завершения команды. Нулевое значение означает успешное выполнение. Проверьте результат, чтобы убедиться в корректности:
if os.system("ls") == 0:
print("Команда выполнена успешно")
os.system("cp source.txt destination.txt")
Если команда содержит пробелы или специальные символы, заключите её в кавычки. Например, для создания директории с пробелом в имени:
os.system('mkdir "My Folder"')
Преимущества и недостатки разных подходов
- Плюсы:
- Простота использования и интеграции в код.
- Поддержка синхронного выполнения команд.
- Минусы:
- Не подходит для асинхронных задач без дополнительных настроек.
- Требует явного указания аргументов для безопасности.
Для асинхронного выполнения команд используйте asyncio.create_subprocess_exec(). Это идеальный выбор, если вы работаете с множеством задач, которые должны выполняться параллельно.
- Плюсы:
- Эффективность при работе с большим количеством задач.
- Интеграция с асинхронным кодом.
- Минусы:
- Сложнее в настройке и отладке.
- Требует понимания асинхронного программирования.
- Плюсы:
- Минимальный код для выполнения команд.
- Подходит для быстрого тестирования.
- Минусы:
- Менее безопасен из-за отсутствия контроля над аргументами.
Для сложных сценариев, где требуется передача данных между процессами, используйте subprocess.Popen(). Этот метод предоставляет максимальную гибкость, но требует больше усилий для настройки.
- Плюсы:
- Подходит для длительных задач и взаимодействия между процессами.
- Минусы:
- Сложный синтаксис и управление.
- Требует ручного закрытия процессов.
Выбор метода зависит от вашей задачи. Для большинства случаев subprocess.run() будет оптимальным решением, сочетающим простоту и функциональность.
import subprocess
result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(result.stdout.decode('utf-8'))
if result.stderr:
print("Ошибка:", result.stderr.decode('utf-8'))
Если команда завершается с ошибкой, проверьте код возврата через result.returncode. Ненулевое значение указывает на сбой. Для автоматического вызова исключения при ошибке добавьте аргумент check=True:
try:
subprocess.run(['invalid_command'], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except subprocess.CalledProcessError as e:
print("Команда завершилась с ошибкой:", e.stderr.decode('utf-8'))
process = subprocess.Popen(['ping', 'google.com'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while True:
output = process.stdout.readline()
if output == b'' and process.poll() is not None:
break
if output:
print(output.decode('utf-8').strip())
Этот подход полезен для длительных операций, где важно получать данные по мере их появления.
Пример:
import subprocess
result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE)
output = result.stdout.decode('utf-8')
print(output)
Пример:
result = subprocess.run(['ls', '/несуществующий_каталог'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
output = result.stdout.decode('utf-8')
error = result.stderr.decode('utf-8')
print('Output:', output)
print('Error:', error)
Пример:
process = subprocess.Popen(['ping', '-c', '4', 'google.com'], stdout=subprocess.PIPE)
for line in iter(process.stdout.readline, b''):
print(line.decode('utf-8').strip())
Управление стандартным потоком ошибок
Чтобы перенаправить стандартный поток ошибок в Python, используйте параметр stderr в модуле subprocess. Например, команда subprocess.run(['ls', '/несуществующий_каталог'], stderr=subprocess.PIPE) захватывает ошибки в переменную для дальнейшей обработки.
Если нужно записать ошибки в файл, откройте файл в режиме записи и передайте его в stderr: with open('errors.log', 'w') as f: subprocess.run(['ls', '/несуществующий_каталог'], stderr=f). Это сохранит все сообщения об ошибках в файл errors.log.
Чтобы игнорировать ошибки полностью, перенаправьте их в subprocess.DEVNULL: subprocess.run(['ls', '/несуществующий_каталог'], stderr=subprocess.DEVNULL). Это полезно, если ошибки не требуют обработки.
Используйте check=True для автоматического вызова исключения при ошибке: subprocess.run(['ls', '/несуществующий_каталог'], check=True). Это остановит выполнение программы, если команда завершится с ошибкой.
import subprocess
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
output = result.stdout
print(output)
lines = output.splitlines()
for line in lines:
print(line)
Если нужно извлечь конкретные данные, используйте регулярные выражения с модулем re. Например, чтобы найти все файлы с расширением .txt, выполните:
import re
txt_files = re.findall(r'bw+.txtb', output)
print(txt_files)
import pandas as pd
from io import StringIO
df_output = subprocess.run(['df', '-h'], capture_output=True, text=True).stdout
df = pd.read_csv(StringIO(df_output), delim_whitespace=True)
print(df)
Если требуется фильтрация данных, применяйте методы pandas, такие как query() или loc[]. Например, чтобы выбрать строки, где использование диска превышает 50%, выполните:
filtered_df = df.query('Use% > "50%"')
print(filtered_df)






