Pull to refresh

Скрипты Python против Bash — 2 или Tips & Tricks

Reading time 4 min
Views 14K
image
Довольно давно я написал статью, в которой приводил примеры основ работы с системой с помощью Python-скриптов. Из-за мельком оброненной фразы (достаточно взглянуть на название топика) статья получила довольно много комментариев холиварного и не очень характера. Кому-то, возможно, захотелось воспользоваться возможностями Python для администрирования (сейчас подобного рода тулзы на питоне как раз набирают популярность). Так почему бы не завлечь в свой стан еще немного единомышленников? :) Встречайте — небольшая подборка простых приемов для тех или иных целей.

Файлы и кое-что еще


Итак, сразу с места в карьер! Для начала возьмем банальную процедуру — копирование файла. До сих пор помню этот ужас, который приходилось писать на голом Си — считывание файла построчно в переменную и перезапись его по другому адресу… Но ведь вполне можно воспользоваться и более простыми методами! :) Первый способ, который придет в голову линуксоиду — это, скорее всего, что-то вроде
Copy Source | Copy HTML
  1. import subprocess
  2. subprocess.Popen('cp /usr/share/file.txt /home/user/file.txt', shell=True)

Только вот подобный способ будет работать только при наличии bash или подобного ему интерпретатора (ну или потребует прописания алиасов). Зачем? Ведь можно воспользоваться методом отличного модуля shutil:
Copy Source | Copy HTML
  1. import shutil
  2. shutil.copyfile("C:\\My Documents\\mydoc.doc", "C:\\My Documents\\mydoc_2.doc")

Переименование делается похожим образом:
Copy Source | Copy HTML
  1. import os
  2. os.rename("/home/user/testfile.txt", "/home/user/test.txt")

Удалить файл можно, соответственно, с помощью os.remove().

Для записи данных в файл можно использовать как питоновый write(), так и «поточный» вариант (сиплюсплюсники, привет вам):
Copy Source | Copy HTML
  1. myfile = open("/home/user/testfile.txt", "w")
  2. print>>myfile, "I want to drink some beer with Guido"
  3. myfile.close()

upd: Более современный метод от юзернейма image bioroot (включен по умолчанию только начиная с версии 2.6, в 2.5 его можно взять из __future__:
>> from __future__ import with_statement ):
Copy Source | Copy HTML
  1. with open("/home/user/testfile.txt", "w") as myfile:
  2.     print>>myfile, "I want to drink some beer with Guido"


Иногда (например, при чтении логов) вам может понадобиться читать файл построчно, начиная с конца. Делается это элементарно:
Copy Source | Copy HTML
  1. for line in reversed(open("/var/log/messages").readlines()):
  2.     print line

А чтобы прочесть строку под определенным номером — можно воспользоваться как стандартным чтением файла в лист, так и использовать модуль linecache:
Copy Source | Copy HTML
  1. line = linecache.getline("C:\\test.txt", 2)
  2. print line
  3. # or
  4. line = open("C:\\test.txt").readlines()[1]
  5. print line

Кстати, бинарный файл читать ничуть не сложнее:
Copy Source | Copy HTML
  1. pic = open("C:\\Pictures\\V4erashnaya_pyanka.bmp", "rb")
  2. buf = pic.read(5) # считываем первые 5 байт
  3. print buf

Кроме того, чтобы не заблудиться:
Copy Source | Copy HTML
  1. print pic.tell() # число байт с начала файла
  2. pic.seek(0) # назад в начало 


Если, например, мы пишем программу с поддержкой плагинов — нам может понадобиться перебор файлов в определенном каталоге:
Copy Source | Copy HTML
  1. for filename in os.listdir("../plugins"):
  2.     print(filename)

Причем можно делать то же самое по маске:
Copy Source | Copy HTML
  1. import glob
  2. for filename in glob.glob("../plugins/*.zip"):
  3.     print filename

Парсим пути:
Copy Source | Copy HTML
  1. print os.path.dirname("/home/user/test.txt")   #имя каталога
  2. print os.path.basename("/home/user/test.txt")   #имя файла

Открываем адрес или локальный файл в браузере по умолчанию (например, при создании ссылок в about-окошках):
Copy Source | Copy HTML
  1. import webbrowser
  2. webbrowser.open('http://www.habrahabr.ru/')
  3. webbrowser.open(u'file://home/user/mysite.html')
  4. webbrowser.open(u'mailto:foo@bar.com?subject=Feedback%20message')

Для определения кодировки строки или файла можно воспользоваться удобным модулем chardet, причем возвращается не только кодировка, но и «уверенность» в том, что она определена правильно, в красивом словарике:
Copy Source | Copy HTML
  1. import chardet
  2. str = open("/home/user/myfile.txt","r").readline()
  3. enc = chardet.detect(str)
  4. print enc['confidence']
  5. print enc['encoding']

Очень удобная вещь когда нужно, например, заюникодить строку с заранее неизвестной кодировкой. Правда, я столкнулся с проблемой определения mac-кодировок (всегда возвращается простой ascii, но на то он и мак, что часть символов кодируется не как обычно). В любом случае, линуксоидам легче — у нас есть enca и iconv :)

Ну что, пока хватит? Если тенденция понравится — попробую продолжить описание применения Python для администрирования системы и напишем пару рабочих примеров. И да, огромное спасибо такой вещи, как Python Cookbook!
Tags:
Hubs:
+51
Comments 113
Comments Comments 113

Articles