Linux bash или python

Скрипты Python против Bash

Поехали!

Чтобы сделать скрипт на языке Python исполняемым в консоли — нужно, чтобы первая строчка имела вид

где /usr/bin/python — адрес интерпретатора Python, установленного в вашей системе. Ну и, естественно, пользователь, запускающий скрипт, должен иметь права для его выполнения. Что характерно, это будет работать только в NIX-системах. В Windows скрипты автоматически становятся исполняемыми при установке соответствия между программой-интерпретатором и типом файлов .py.

В целом скрипты Python во многом похожи на скрипты Bash, однако, на мой взгляд, они куда изящнее. Рассмотрим основные функции, которые могут нам понадобиться:

listdir(path)
Возвращает список имен файлов и папок в папке с именем path.

mkdir(path)
Создает папку с именем path.

makedirs(path)
Работает аналогично функции mkdir(), но автоматически создает все необходимые промежуточные папки.

remove(path)
Удаляет файл с именем path.

rmdir(path)
Удаляет каталог с именем path.

removedirs(path)
Работает аналогично функции rmdir(), но автоматически удаляет все родительские пустые папки.

rename(src, dst)
Переименовывает файл или папку с именем src в dst.

open(filename, flag)
Открывает файл с именем filename. Flag нужен для определения режима доступа: «r» — чтение, «w» — запись, «a» — дописывание.

read(size)
Считывает из файла данные размером size и возвращает в виде строки. Если аргумент опущен, то считывается все содержимое файла.

readline()
Считывает из файла одну строку, включая символ перехода на новую строку («\n»).

readlines()
Считывает из файла все строки и возвращает их в виде списка.

write(string)
Записывает строку string в файл.

writelines(lines)
Записывает строки из списка lines в файл. Символ перехода на новую строку между ними не добавляется.

tell()
Возвращает текущее положение в файле в байтах от начала файла.

seek(offset, whence)
Изменяет положение на offset. Характер определения положения зависит от аргумента whence (по умолчанию 0):
1) 0 – новое положение отсчитывается от начала файла;
2) 1 – от конца файла;
3) 2 – от текущего положения в файле;

truncate(size)
Усекает файл до размера size.

close()
Закрытие файла. Запомните! Любое открытие файла должно сопровождаться последующим закрытием с помощью этого метода.

А теперь — к более частным случаям.

Каша в голове? Ничего, сейчас мы разберем все подробнее.

Первым делом добавим немного интерактивности. Иначе смысл в нашем скрипте, если он ничего не будет спрашивать у пользователя? 🙂 Для ввода с клавиатуры используется метод raw_input(). Почему не просто input()? Потому что при считывании строки через input() она пропускается через интерпретатор, преобразующий введенную строку в команду. Руки так и чешутся ввести rm -rf… Ну ладно, погнали дальше! Синтаксис у функции такой:

login = raw_input(«Enter your name: «)
Здесь login — переменная, в которую считывается после нажатия Enter введенная пользователем строка.
Теперь давайте откроем файл и запишем в него какую-нибудь информацию.

gogo = open («/home/username/helloworld»,»w»)
gogo.write(«Hello, world!»)
gogo.close()

Кстати, рекомендую проверить, перед тем, как исполнять вышенаписанное, не завалялся ли у вас какой-нибудь нужный файл по адресу /home/username/helloworld? А то ведь все в нем сотрет и ничего не оставит на месте преступления, кроме «Hello, world!».

Ну а теперь давайте поработаем напрямую с консолью. Лично я в одном фрагменте кода доставал из выдачи команды host domen.com адрес хоста своего провайдера. Сказано — сделано.

import os
import re
vid = os.popen(«host l2tp.corbina.ru»)
re_dns = re.compile(r»([\d]+)\.([\d]+)\.([\d]+)\.([\d]+)»)
for line in vid.readlines():
&nbsp hst=re_dns.search(line)
&nbsp if (hst != None):
&nbsp &nbsp break
host=hst.group(0)
print «Corbina host adress is «+host

Ух ты, сколько всего… Ну, давайте разбираться. Построчно.

import os
import re
Подключаем стандартные библиотеки питона, чтобы все работало. os — библиотека для работы с системными вызовами и консолью. re — для работы с регулярными выражениями.

vid = os.popen («host l2tp.corbina.ru»)
Здесь мы как бы «вводим в консоль» команду host l2tp.corbina.ru, а то, что получилось, запихиваем в виде списка в переменную vid.

re_dns=re.compile(r»([\d]+)\.([\d]+)\.([\d]+)\.([\d]+)»)
Это, друзья мои, преобразование регулярного выражения. re_dns — это переменная, в которую записывается особый объект, полученный при помощи метода re.compile(). Сам синтаксис регулярного выражения я объяснять не буду, тем более что он простейший, скажу только — это самый простой вариант фильтра для IP-адресов.

Читайте также:  Открыть bitlocker windows 10

for line in vid.readlines():
Здесь стартует цикл for. Думаю, вы уже заметили, что в языке Python синтаксис цикла for довольно сильно отличается от других языков. Здесь берется переменная line, в которую по очереди записываются строки из списка vid.readlines(). Закончатся строки в списке — закончится и цикл. Двоеточие в конце обозначает начало раздела операторов, которые происходят в цикле. Эти операторы должны отделяться табуляцией или несколькими пробелами. Как только мы написали все, что должно происходить в цикле — просто пишем очередной оператор с начала строки. Кстати, это также касается и условного оператора if, как видно ниже.

hst=re_dns.search(line)
А здесь мы применяем полученный ранее объект регулярного выражения к строке line, в результате чего в hst возвращается либо список подходящих под него строк, либо None в случае, если ничего не найдено.

if (hst != None):
&nbsp break
Проверка на тот самый None. Обратите еще раз внимание на отступ перед break. Как вы, наверное, знаете из других языков, этот самый break является оператором прерывания цикла. Таким образом, как только hst становится не равен None — цикл прерывается.

host=hst.group(0)
Как я уже говорил, в переменную hst возвращается список подходящих под регулярное выражение строк. На самом деле, точнее говоря, возвращается не список, а кортеж элементов. А поскольку мы прервали цикл, как только нашли первую подходящую строку — она и запишется в первый (он же нулевой) элемент кортежа, который мы благополучно достаем и записываем в host.

print «Corbina host adress is «+host
А потом выводим этот айпишник в консоль. Оператор print выводит переданную ему строку в консоль, да еще и допускает конкатенацию строк простым сложением.

Ну, собственно, вот и все для начала. Попрошу особо не ругать и не пинать за рваность повествования, если есть какие-то нарекания — с радостью прислушаюсь и постараюсь исправить.

Источник

Что лучше использовать: питон или баш?

Для системных скриптов, скриптов бекапа и прочего. Обычно строк на 20-100. Много видел тут сообщений о том, что лучше питон чтобы не стрелять себе в ногу башем, но не знаю… как то куча сабпроцесов для вызова системных утилит намекает на то, что инструмент все же не тот. Как считаете? Имеется ввиду если нужно обернуть имеджмэджик, рсинк или еще что то с подготовкой в виде создания папок, проверками на существование, изменение имени по маске или поиск и прочее.

На баше очень муторно писать всякие проверки и всё такое

Лучше баш, ибо пистон каждый год ломают всё больше.

Будешь только и делать, что переписывать скрипты и обновлять пистон.

Проверки, о которых пишет ТС, что на баше, что на питоне представляют собой однострочники вида

И это если не сокращать баш до && и || в одной строке.K

А проверки завершения вызываемых утилит?

проверки завершения вызываемых утилит

Путь первый. Выучиваешь Bash по тому же Advanced Bash Scripting Guide. Устаешь молотить данные сторонними утилитами с бесконечным ворохом разнородных параметров. Идешь учить Python.

Путь второй. Выучиваешь Python по паре-тройке онлайн-курсов. Устаешь дергать разнородные библиотеки или сочинять громоздкие вызовы внешних утилит для примитивнейших операций. Идешь учить Bash.

Конечный итог. Ты знаешь Bash и Python и выбираешь инструмент под задачу вместо «я тебя слепила из того, что было».

Пользуйся чем хочешь. Только для bash не забывай использовать shellcheck.

А ещё есть set -euo pipefail , но с ним которые привычки ломаются.

Для работы с запуском программ и с файлами — однозначно баш лучше. Есть всякие правила, которые надо соблюдать — про кавычки вокруг аргументов например. Но и в питоне те-же самые проблемы, если использовать тот вариант subprocess, который принимает строку, а не список (не надо его использовать).

Начни на баше. После первого rm -rf $dir/* когда dir внезапно окажется неопределенным — переходи на питон.

зависит от задачи

Лучше использовать то, что лучше знаешь. Мне проще на шелле наговнокодить и использовать с уверенностью, что заработает везде, даже где нет питона. Часть мелкой фигни у меня используется на домашнем сервере, на нём питона нет, потому что его ничего не тянет и он не нужен. Хотя изначально была даже мысля таскать со скриптами статичную сборку микропитона.

Читайте также:  Как задать имя пользователя windows 10

Для работы с запуском программ и с файлами — однозначно баш лучше.

Вот тут однозначно плюс. Меньше эболы с вызовом внешних утилит и получения их кодов возврата.

На баше очень муторно писать всякие проверки и всё такое

Да с хера ли. [ -x /tools/getstat ] && /tools/getstat -ololo как будет выглядеть на питоне?

// Я питон люблю, но он однозначно не для всяких мелких скриптов.

Вот для этого есть set -u и прочее.

а) Проще поддерживать, в том числе когда ты уйдешь из конторы.

б) Байки про несовместимость — байки. Любой инфрушный скрипт написанный на python 3 взлетит на любом python 3 (если автор сознательно не упарывался). Аналогично в рамках 2ой версии.

Есть всякие правила, которые надо соблюдать

Проблема зачастую в том, что вместо понимания как программировать на языке, пытаются выработать «привычки». Чем такая привычка поможет когда надо вызвать: $PRG $add_arguments , где и первая и вторая переменные явно содержат аргументы через пробелы с вашей «привычкой», где «явно» натурально обозначает «сформировано специально с учётом отсутствия спецэффектов»?

Источник

Пишем shell скрипты на Python и можно ли заменить им Bash

В этой небольшой статье речь пойдет о том, можно ли легко использовать Python для написания скриптов вместо Bash/Sh. Первый вопрос, который возникнет у читателя, пожалуй, а почему, собственно, не использовать Bash/Sh, которые специально были для этого созданы? Созданы они были достаточно давно и, на мой взгляд, имеют достаточно специфичный синтаксис, не сильно похожий на остальные языки, который достаточно сложно запомнить, если вы не администратор 50+ левела. Помните, ли вы навскидку как написать на нем простой if?

Элементарно правда? Интуитивно понятный синтаксис. 🙂

Тем не менее в python эти конструкции намного проще. Каждый раз когда я пишу что то на баше, то непременно лезу в поисковик чтобы вспомнить как писать простой if, switch или что-то еще. Присвоение я уже запомнил. 🙂 В Python все иначе. Я хоть и не пишу на нем круглые сутки, но никогда не приходилось лезть и смотреть как там сделать простой цикл, потому что синтаксис языка простой и интуитивный. Плюс ко всему он намного ближе к остальным мейнстримовым языкам типа java или c++, чем Bash/Sh.

Также в стандартной и прочих библиотеках Python есть намного более удобные библиотеки чем консольные утилиты. Скажем, вы хотите распарсить json, xml, yaml. Знаете какой я недавно видел код в баше чтобы сделать это? Правильно:

И это был не мой код. Это был код баше/питоно нейтрального человека.

То же самое с регексом, sed бесспорно удобная утилита, но как много людей помнит как правильно ее использовать? Ну кроме Lee E. McMahon, который ее создал. Да впринципе многие помнят, даже я помню как делать простые вещи. Но, на мой взгляд, в Python модуль re намного удобнее.

В этой небольшой статье я хотел бы представить вам диалект Python который называется shellpy и служит для того, чтобы насколько это возможно заменить Bash на python в скриптах.

Введение

Shell python ничем не отличается от простого Python кроме одной детали. Выражения внутри grave accent символов ( ` ) в отличие от Python не является eval, а обозначает выполнение команды в шелле. Например

выполнит ls -l как shell команду. Также возможно написать все это без ` в конце строки

и это тоже будет корректным синтаксисом.

Можно выполнять сразу несколько команд на разных строках

и команды, занимающие несколько строк

Выполнение каждого выражения в shellpy возвращается объект класса Result

Это можно быть либо Result либо InteractiveResult (Ссылки на гитхаб с документацией, можно и потом посмотреть 🙂 ). Давайте начнем с простого результата. Из него можно легко получить код возврата выполненной команды

И текст из stdout и stderr

Можно также пробежаться по всем строкам stdout выполненной команды в цикле

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

Или же более простым способом получить текст из stdout

Все вышеперечисленное — это обзор синтаксиса вкратце, чтобы просто понять основную идею и не грузить вас всеми-всеми деталями. Там есть еще много чего и для интерактивного взаимодействия с выполняемыми командами, для управления исполнением команд. Но это все детали, в которые можно окунуться в документации (на английском языке), если сама идея вам покажется интересной.

Читайте также:  Выпадающая панель для windows

Это ж не валидный синтаксис Python получается, как все работает то?

Магия конечно, как еще 🙂 Да, друзья мои, мне пришлось использовать препроцессинг, каюсь, но другого способа я не нашел. Я видел другие библиотеки, которые делают нечто подобное, не нарушая синтаксиса языка вроде

Но меня такой синтаксис не устраивал, поскольку даже несмотря на сложности, хотелось получить best user experience ©, а для меня это значит насколько это возможно простое и близкое к его величеству Шеллу написание команд.

Знакомый с темой читатель спросит, чем IPython то тебя не устроил, там ж почти как у тебя только значок другой ставить надо, может ты просто велосипедист, которому лень заглянуть в поисковик? И правда он выглядит вот так:

Я его пытался использовать но встретил пару серьезных проблем, с которыми ужиться не смог. Самая главная из них, то что нет простого импорта как в Python. То есть ты не можешь написать какой-то код на самом ipython и легко его переиспользовать в других местах. Невозможно написать для своего ipython модуля

и чтобы все сразу заработало как в сказке. Единственный способ переиспользовать скрипт, это выполнить его. После выполнения в окружении у тебя появляются все функции и переменные, объявленные в выполняемом файле. Не кошерно на мой взгляд.

В shellpy код переиспользуется легко и импортируется точно так же как и в обычном python. Предположим у нас есть модуль common в котором мы храним очень полезный код. Заглянем в директорию с этим модулем

Итак, что у нас тут есть, ну во первых init, но с расширением .spy. Это и является отличительной чертой spy модуля от обычного. Посмотрим также внутрь файла common.spy, что там интересного

Мы видим что тут объявлена функция, которая внутри себя использует shellpy синтаксис чтобы вернуть результат выполнения `echo 5. Как этот модуль используется в коде? А вот как

Видите? Как в обычном Python, просто взяли и заимпортировали.

Как же все работает. Это работает с помощью PEP 0302 — New Import Hooks. Когда вы импортируете что-то в своем коде то вначале Python спрашивает у хука, нет ли тут чего-то твоего, хук просматривает PYTHONPATH на наличие файлов *.spy или модулей shellpython. Если ничего нет, то так и говорит: «Ничего нету, импортируй сам». Если же он находит что-то там, то хук занимается импортом самостоятельно. А именно, он делает препроцессинг файла в обычный python и складывает все это добро в temp директорию операционной системы. Записав новый Python файл или модуль он добавляет его в PYTHONPATH и за дело берется уже самый обыкновенный импорт.

Давайте же скорее посмотрим на какой-нибудь пример

Этот скрипт скачивает аватар юзера Python с Github и кладет его в temp директорию

Установка

Shellpython можно установить двумя способами: pip install shellpy или склонировав репозиторий и выполнив setup.py install . После этого у вас появится утилита shellpy .

Запустим же что-нибудь

После установки можно потестировать shellpython на примерах, которые доступны прямо в репозитории.

Также здесь есть allinone примеры, которые называются так, потому что тестируют все-все функции, которые есть в shellpy. Загляните туда, чтобы лучше узнать что же там еще такого есть, либо просто выполните

Для третьего Python команда выглядит вот так

Совместимость

Это работает на Linux и должно работать на Mac для Python 2.x и 3.x. На виндовсе пока не работает, но проблем никаких для работы нет, так как все писалось с использованием кроссплатформенных библиотек и ничего платформоспецифичного в коде нет. Просто не дошли руки еще, чтобы потестировать на виндовсе. Мака у меня тоже нет, но вроде у друга работало 🙂 Если у вас есть мак и у вас все нормально, скажите пожалуйста.

Если найдете проблемы — пишите в коммент, либо сюда либо телеграфируйте как-нибудь 🙂

Документация (на английском)

Можно ли законтрибьютить

Оно мне ничего в продакшене не разломает?

Сейчас версия 0.4.0, это не стейбл и продакшн процессы пока лучше не завязывать на скрипт, подождав пока все отладится. Но в девелопменте, CI можно использовать вполне. Все это покрыто тестами и работает 🙂

Источник

Оцените статью