Перебор точек монтирования с использованием Python

#python #mount #nfs #linux-disk-free

#python #оболочка

Вопрос:

Как мне выполнить итерацию по точкам монтирования системы Linux с использованием Python? Я знаю, что могу сделать это с помощью команды df, но есть ли встроенная функция Python для этого?

Кроме того, я просто пишу скрипт на Python для мониторинга использования точек монтирования и отправки уведомлений по электронной почте. Было бы лучше / быстрее сделать это как обычный сценарий оболочки по сравнению со сценарием Python?

Спасибо.

Комментарии:

1. Зависит. Что вы подразумеваете под «монитором»? Если вы просто хотите отправить электронное письмо, когда что-то изменится, это будет очень легко сделать в bash, но если вы хотите что-то более сложное, вы быстро обнаружите, что python — это правильный путь.

2. Извините, я имел в виду написать задание cron, которое проверяет пространство, занятое во всех точках монтирования, и отправляет электронное письмо, если оно достигает определенного порога.

3. Почему бы не использовать оба? @ventsyv, справедливо указано, что bash был бы очень прост для доступа к файлам в системе Linux. Отправка уведомлений по электронной почте также может быть выполнена с помощью bash, но, однако, может быть легко выполнена на python, и вы можете создать простой скрипт bash для объединения этих скриптов.

Ответ №1:

Python и кроссплатформенный способ:

 pip install psutil  # or add it to your setup.py's install_requires
 

А потом:

 import psutil
partitions = psutil.disk_partitions()

for p in partitions:
    print p.mountpoint, psutil.disk_usage(p.mountpoint).percent
 

Комментарии:

1. psutil это отличный пакет для получения системной информации, который работает на всех основных платформах и заслуживает лучшей известности.

2. примечательно, /proc что в этом инструменте не отображаются такие вещи, как

Ответ №2:

Запуск mount команды из Python — не самый эффективный способ решения проблемы. Вы можете применить ответ Халида и реализовать его на чистом Python:

 with open('/proc/mounts','r') as f:
    mounts = [line.split()[1] for line in f.readlines()]        

import smtplib
import email.mime.text

msg = email.mime.text.MIMEText('n'.join(mounts))
msg['Subject'] = <subject>
msg['From'] = <sender>
msg['To'] = <recipient>

s = smtplib.SMTP('localhost') # replace 'localhost' will mail exchange host if necessary
s.sendmail(<sender>, <recipient>, msg.as_string())
s.quit()
 

где <subject> , <sender> и <recipient> должны быть заменены соответствующими строками.

Комментарии:

1. Может быть, не самый эффективный, однако /proc/mounts не существует на BSD. Операционная система использует Linux, однако я лично использую mount для таргетинга на более широкий спектр операционных систем.

2. Верно, но в OP конкретно упоминается Linux.

3. Да, я сразу обновил свой комментарий, вы поймали его до того, как я смог сохранить свою правку. Вы правы. /proc/mount имеет один недостаток в Linux. Если вы создаете среду chroot и выполняете mount -o bind это в chroot, в /proc/mounts не будет указано ни одно из подключенных подключений. Однако команда mount (внутри chroot) будет. df тоже не будет, поэтому я предпочитаю запускать mount .

4. привязка mount -o является обычным явлением в linux chroots, поскольку для монтирования нет физических блочных устройств (пути не ведут непосредственно к блочному устройству). Однако выполнение mount -o bind в системе Linux обычно не отображается /proc/mounts (по крайней мере, ни в одном ядре / дистрибутиве Linux, о котором я пока знаю). Однако mount также покажет вам монтирование, выполненное с привязкой -o .

5.@MichaelPetch /proc/mounts перечисляет файловые mount -o bind системы, смонтированные с. Однако это делает это запутанным образом (поле «устройство» в физическом устройстве, а не в привязанном каталоге, а параметры типа / монтирования файловой системы не указывают на его привязку к монтированию). Ну, по крайней мере, в Fedora 20, ядро 3.16.2 это так.


Ответ №3:

Способ bash сделать это, просто для удовольствия:

 awk '{print $2}' /proc/mounts | df -h | mail -s `date  %Y-%m-%d` "you@me.com"
 

Комментарии:

1. open('/proc/mounts').read() это начало для Python. (Кстати, потрясающий ответ)

Ответ №4:

Я не знаю ни одной библиотеки, которая это делает, но вы могли бы просто запустить mount и вернуть все точки монтирования в список с чем-то вроде:

 import commands

mount = commands.getoutput('mount -v')
mntlines = mount.split('n')
mntpoints = map(lambda line: line.split()[2], mntlines)
 

Код извлекает весь текст из mount -v команды, разбивает выходные данные на список строк, а затем анализирует каждую строку для третьего поля, которое представляет путь к точке монтирования.

Если вы хотите использовать df then, вы тоже можете это сделать, но вам нужно удалить первую строку, содержащую имена столбцов:

 import commands

mount = commands.getoutput('df')
mntlines = mount.split('n')[1::] # [1::] trims the first line (column names)
mntpoints = map(lambda line: line.split()[5], mntlines)
 

Как только у вас есть точки монтирования ( mntpoints список), вы можете использовать for in для обработки каждого из них такой код:

 for mount in mntpoints:
    # Process each mount here. For an example we just print each
    print(mount)
 

В Python есть вызываемый модуль обработки почты smtplib , и информацию можно найти в документах Python

Комментарии:

1. Спасибо, Майкл. Является ли commands.getoutput лучше, чем Subprocess.popen, если я хочу выполнить итерацию по результату команды оболочки?

2. Для чего-то подобного я считаю getoutput более удобным, если вы хотите перенаправить вывод stdin и stdout в строку. Subprocess.popen позволяет вам делать гораздо больше с каналами. Если вам нужен более точный контроль перенаправления getoutput , это не лучший вариант. getoutput в частности, возвращает все данные из stdin и stderr и сбрасывает их в строку (в данном случае вызываемую строку mount ). Очень удобно, если все, что вам нужно, это весь вывод в одной большой текстовой строке. Вы можете использовать Subprocess.popen для выполнения той же работы больше кода.