Верстакфорум практиков
рекламаiprazon: приватные серверные адреса IPv4 и SOCKS5, безлимитный трафик, бесплатный тест до 2 часов
ФорумСкрипты и автоматизация

Bash или Python для обвязки: что где удобнее

stackfix
stackfix
Участник
сообщений 495
с окт
1 января, 08:12первое сообщение

Обвязка вокруг прогона растёт сама собой: забрать список, разложить по пачкам, дёрнуть парсер, собрать выгрузки, сложить в архив, отписать в чат. Начиналось с двадцати строк на sh, сейчас там триста и я в них путаюсь.

Переписывать на питон или дожимать оболочку? Интересует именно граница: где заканчивается удобство одного и начинается удобство второго.

пишу скрипты, чтобы не писать скрипты
dev_null_ru
dev_null_ru
Ветеран
сообщений 2560
с фев
8 июня, 11:29#2

Граница проходит по данным. Пока скрипт двигает файлы и запускает процессы, оболочка вне конкуренции, у неё это родной язык.

Как только внутри заводятся структуры, вложенные поля, разбор ответа, состояние между шагами, оболочка превращается в набор подпорок вокруг jq и awk. Триста строк это уже сигнал.

Тимур Ш.
Тимур Ш.
Участник
сообщений 890
с июн
15 ноября, 14:46#3

Добавлю по своему опыту. Язык тут вторичен, больнее всего бьёт отладка.

Скрипт на sh в триста строк падает молча и в неожиданном месте, потому что по умолчанию он едет дальше после любой ошибки. Первое, что вписывают в любой такой скрипт длиннее экрана:

set -euo pipefail
IFS=$'\n\t'

Без этих двух строк ваши триста живут своей жизнью и вы про это узнаёте по кривой выгрузке.

бэкап перед правкой конфига
skript_kid
skript_kid
Новичок
сообщений 54
с сен, второй сезон
22 апреля, 17:03#4

а что делает pipefail? у меня и без него вроде падает

dev_null_ru
dev_null_ru
Ветеран
сообщений 2560
с фев
1 сентября, 08:20#5

pipefail меняет код возврата конвейера. По умолчанию код берётся у последней команды, поэтому вот такая строка считается успешной, хотя первая половина легла:

curl -s https://example.org/spisok | grep -c 'tovar'

curl отвалился, grep честно посчитал ноль совпадений и вернул своё. Скрипт едет дальше с пустым списком. С pipefail код конвейера станет ненулевым, и вместе с set -e прогон остановится.

Дальше места, где оболочка кусается именно на длинных скриптах:

  • пробелы в путях: любая переменная без кавычек разлетается на слова;
  • пустая переменная в rm -rf "$katalog"/ выносит корень целиком;
  • арифметика только целая, среднее время отклика посчитать нечем;
  • разбор JSON без jq невозможен, а с jq вы уже пишете на втором языке внутри первого;
  • функции возвращают только код, всё прочее едет через вывод и подстановку.

Поодиночке ничто из этого не смертельно. Вместе на трёхстах строках получается механизм, который держится на памяти автора.

stackfix
stackfix
Участник
сообщений 495
с окт
8 февраля, 11:37#6
dev_null_ru: превращается в набор подпорок вокруг jq и awk

Вот это прямо про меня. Шесть вызовов jq подряд, и каждый раз я заново читаю один и тот же файл. Долю отказов пришлось считать через awk, потому что оболочка целочисленная.

Значит, режу пополам?

пишу скрипты, чтобы не писать скрипты
Максим Юрьев
Максим Юрьев
Знаток
сообщений 1720
с апр
15 июля, 14:54#7

Именно пополам. Схема, которая у меня прижилась: оболочка остаётся снаружи и делает то, что умеет лучше всех, запуск, замки, перенаправление вывода, коды возврата. Всё, что думает, уезжает в питон и вызывается как обычная команда.

#!/bin/sh
set -eu
flock -n /var/lock/progon.lock python3 -m obvyazka.progon --pachka 500

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

mila_ops
mila_ops
Новичок
сообщений 175
с апр, второй сезон
22 декабря, 17:11#8

а питон на голом сервере без сети как ставить? у нас закрытый контур

Тимур Ш.
Тимур Ш.
Участник
сообщений 890
с июн
1 мая, 08:28#9

Стандартной библиотеки хватает на девять задач из десяти. urllib, json, sqlite3, csv, concurrent.futures уже внутри, ставить нечего.

бэкап перед правкой конфига
Максим Юрьев
Максим Юрьев
Знаток
сообщений 1720
с апр
8 октября, 11:45#10

Если внешние пакеты всё же понадобятся, соберите колёса на машине с сетью и перенесите папкой, дальше pip install --no-index --find-links. Виртуальное окружение кладите рядом со скриптом, тогда переезд на другую машину сводится к копированию каталога.

skript_kid
skript_kid
Новичок
сообщений 54
с сен, второй сезон
15 марта, 14:02#11

о, про колёса не знал, спасибо

dev_null_ru
dev_null_ru
Ветеран
сообщений 2560
с фев
22 августа, 17:19#12

И оставьте себе право на однострочник. Половина задач так и остаётся тремя строками на sh, тащить туда питон незачем.

stackfix
stackfix
Участник
сообщений 495
с окт
1 января, 08:36#13

Разрезал за вечер. Снаружи sh на сорок строк: замок, обход трёх поставщиков, вызов питона на каждого, архив и отправка в чат. Внутри питон на двести с небольшим строк, куда уехал весь разбор и подсчёты.

Отладка сразу стала человеческой: падает с внятной трассой и на понятной строке. Заодно set -euo pipefail в оставшемся куске поймал две старые ошибки в первый же вечер.

пишу скрипты, чтобы не писать скрипты