LINUX.ORG.RU

Подход к написанию скриптов (я один такой?)

 


1

3

Привет

По работе приходится писать bash скрипты. У тут дилемма: писать так, чтоб работало на целевых серверах, или чтобы работало везде; ведь теоретически мой скрипт могут переиспользовать. Плюс, есть уйма нестандартных ситуаций: что-то может глюкануть, что-то может измениться после апгрейда и т. п.; вероятность таких ситуаций - что-то около 0.01%, но ведь это возможно.

И это абсолютно разные задачи.

Недавно попался показательный пример. Есть bash скрипт, который, по сути своей, состоит из около 5 строк. Следуя принципу «чтобы работало везде» я его раздул до 350 (!). Там было всё: проверка наличия необходимых утилит в системе, логирование, проверка что файловая система не read-only, даже проверка на то, что у меня именно GNU sed. Всё сдобрено обильными комментариями, на случай поддержки другим человеком.

Всё работает. Но...

Вот теперь сижу и думаю: 5->350 это нормально? Я один такой?

Один товарищ глянув на это изрёк: «здоровая паранойя программиста». Я так и не понял, был ли это комплемент или нет.

Считаете ли вы такой подход правильным? Кто еще пишет скрипты «на все случаи жизни»?

★★★★★

Последнее исправление: Kroz (всего исправлений: 4)

«чтобы работало везде»

Поскольку «везде» — понятие безграничное, то и процесс написания такого скрипта получится бесконечным. Нужно где-то проводить границу. Например, брать стандарт POSIX, как ограничивающий.

5->350

Звучит не очень реалистично. Покажи оба варианта.

anonymous
()

Я считаю, что в этом плохого ничего нет, если нужно скрипт который будет работать ТОЛЬКО при определённых условиях(GNU sed, или специфический дистрибутив) без проверок никуда

Deleted
()

дилемма

>_<

Вот теперь сижу и думаю: 5->350 это нормально?

Для меня это нормально, но.

Но если у меня стоит задача писать, чтобы работало действительно везде, я пишу под POSIX Shell, не юзаю GNUтые расширения и у меня выходит из возможных пяти строк все восемьсот, ибо нет арраев и многое, что в баше решается просто, приходится костылять. А писать шелл-"библиотеку" мне всё время лень.

r3lgar ★★★★★
()

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

peregrine ★★★★★
()
Ответ на: комментарий от Deleted

Типа хелперы. Чтобы не пользоваться гнутыми расширениями и арраями из баша, писать под POSIX Shell, но не раздувать код, юзая костыли из типа библиотеки, а не писать каждый раз костыли в новом скрипте. В итоге у меня куча повторяющегося (хоть и не тупой копипасты) кода в скриптоте.

r3lgar ★★★★★
()
Ответ на: комментарий от r3lgar

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

Может в этом случае проще взять перл или пайтон? Или пишешь для таких мест, где и перла может не оказаться?

anonymous
()

это bash говно, а не подход

5->350 это нормально?

нет

anonymous
()
Ответ на: комментарий от anonymous

Может в этом случае проще взять перл или пайтон? Или пишешь для таких мест, где и перла может не оказаться?

Питона в FreeBSD точно искаропки нет. А на Perl некоторые вещи писать сильно накладно (я тут пилил одну штуковину, и когда уже почти дописал, оказалось, что Perl дереференсит симлинки, вот щаз думаю, на чём переписывать — на POSIX Shell, или на сях).

r3lgar ★★★★★
()
Ответ на: комментарий от Deleted

эти «библиотеки» подключаются с помощью source?

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

r3lgar ★★★★★
()

5->350 это нормально?

Нет. Даже если просто проверить утилиты перед запуском, не должно быть такого раздувания. Возможно, дело в том, что ты пытаешься поддерживать сразу несколько версий утилит? Это лишнее. Достаточно просто проверить и вывалиться с ошибкой.

Я один такой?

Нет. Все в той или иной степени страдают чем-то подобным. Называется «пунктик».

был ли это комплемент или нет.

Нет. Но и порицанием это не было.

Считаете ли вы такой подход правильным?

Нет. Bash это вообще что-то странное. Недавно узнал, что у него свои реализации malloc/realloc/free.

i-rinat ★★★★★
()
Ответ на: комментарий от r3lgar

оказалось, что Perl дереференсит симлинки

А можно об этом чуть подробнее? Чтобы в будущем не напороться.

anonymous
()

ведь теоретически мой скрипт могут переиспользовать.

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

splinter ★★★★★
()
Ответ на: комментарий от anonymous

оказалось, что Perl дереференсит симлинки

А можно об этом чуть подробнее? Чтобы в будущем не напороться.

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

r3lgar ★★★★★
()
Ответ на: комментарий от i-rinat

Bash это вообще что-то странное.

Я всегда говорил, что bash вообще лучше не трогать для скриптов. Если для чего-то не хватает возможностей POSIX shell'а, то тогда уж сразу полноценный язык брать.

Отдельно замечу, что тех, кто пишет #!/bin/sh, а потом в коде использует башизмы, надо убивать^Wучить так не делать. Никогда! Простите, наболело.

anonymous
()
Ответ на: комментарий от anonymous

пишет #!/bin/sh, а потом в коде использует башизмы

В Debian это уже давно не работает, там поменяли скриптовый шел на dash. И это хорошо. Тогда загрузка стала заметно быстрее.

i-rinat ★★★★★
()
Ответ на: комментарий от r3lgar

Perl не умеет копировать симлинк как симлинк

Это File::Copy?

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

Не, ну можно же накостылить что-нибудь и на перле, хоть тот же системный cp вызвать.

anonymous
()
Ответ на: комментарий от anonymous

Это File::Copy?

В первую очередь он, да.

Не, ну можно же накостылить что-нибудь и на перле, хоть тот же системный cp вызвать.

Так и сделал, но мне это сильно не нравится (и не в последнюю очередь тем, что во фряхе аргументы у cp отличаются).

r3lgar ★★★★★
()
Последнее исправление: r3lgar (всего исправлений: 1)
Ответ на: комментарий от anonymous

можно прочитать линк и пересоздать самому в новом месте

Нельзя. Мне нужно скопировать исходный файл, каким бы он ни был, чтобы восстановить его (бэкап конфигов). Причём если это симлинк с относительными путями, или нет файла, или циклическая линковка (а это совсем задница!), то можно огрести на ровном месте.

На stackoverflow так и предлагают

Да, когда я этот вопрос исследовал, этот вопрос всплыл одним из первых, но он не покрывает странные вещи (в предыдущем абзаце есть примеры).

r3lgar ★★★★★
()

Пишу, чтобы работало везде (обычно просто используя POSIX Shell, без надстроек Bash), но до 350 строк вместо 5 не доходило. Думаю, это уже перебор. Даже 2x строк это уже перебор. Во всём нужна мера, и всё же 5-строчный скрипт это 5-строчный скрипт, а не программа на века. В противном случае её следовало писать не на Bash вовсе, а хотя бы на Python (или другом скриптовом, но полноценном языке по вкусу), а то и на компиллируемом в натив чём-то (C или там Rust).

Psych218 ★★★★★
()

Баш-скрипты всегда пишутся «на выброс», так что смысла особого нет.

лучше пусть у тебя будет несколько 5-строчных версий под конкретный тип системы. Нужный вариант выбирать симлинком, как делает debian'овский update-alternatives.

anonymous
()

Так вы можете показать две версии своего скрипта или нет ?

bryak ★★★★
()

Так ты с плохой стороны подходишь - надо убедится что система подходит для твоего скрипта, а не приспосабливать свой скрипт для любой системы. Короткая проверка фичей в начале + сам скрипт, если проверка прошла. Уж лучше приспосабливать короткий скриптик к другому башу, чем выяснять, что там в огромном блобе на все случаи жизни умудрилось пойти не так.

anonymous
()

Считаете ли вы такой подход правильным? Кто еще пишет скрипты «на все случаи жизни»?

Я считаю, что если тебе приходится писать и массово и активно использовать bash-скрипты, то с тобой или с твоими серверами что-то ни так.
Пиши под salt, ansible или под ту систему оркестрации, которой ты непользуешься.

anonymous_sama ★★★★★
()
Ответ на: комментарий от anonymous

Пример:

#!/bin/bash

TEST_FILE='/tmp/bash-test.tmp'
TEST_CMD=$((echo "qqq" > $TEST_FILE) && (sed -i s/q/a/g $TEST_FILE) && (cat $TEST_FILE) && (rm $TEST_FILE))

if [ "$TEST_CMD" = "aaa" ]; then
    echo "Test passed :)"
    else
    echo "Fail :("
fi
anonymous
()

Это какая-то разновидность ОКР. В решениях ad hoc нет ничего скверного, а вот навязчивое желание каждый местный скриптик раздуть в глобальный продукт - трэш мозга.

Deleted
()

пишет скрипты «на все случаи жизни»

Ты неправильно ставишь задачу. Делай скрипт максимально понятным.

anonymous
()

Тут надо разделять задачи скрипта и программы.

init_6 ★★★★★
()
Ответ на: комментарий от anonymous

Так получше напиши. Я хоть какой-то пример привёл, а от тебя, детка, только пустой лай.

anonymous
()

Просто пишу #!/bin/bash и не парюсь. Кому надо будет — тот переделает под себя сам. Ну или поставить баш — одна команда, ни у кого ещё руки не отвалились.
Никто же не парится используя перл, или питон, определённой версии. Если надо какую-то программу, то никто же не парится по поводу библиотек, которые ей нужны. А часто бывает, что и дистрибутив надо именно конкретный ибо поставщик не осилил по другому. Да что там другой дистрибутив — альтернативную операционку вынь да выложь. Обмазываются контейнерами, виртуалками и прочей жиротой ради так называемого выполнения задачи. А тут какие-то рефлексии. Нужно обязательно рассказать на форуме какое говно этот баш, чтобы анонимы зауважали.

imul ★★★★★
()

5->350 это нормально?

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

redgremlin ★★★★★
()

Я склоняюсь к принципу большинства. Почти везде баш, а значит поддерживать то, где шелл несовместим с башем я не буду. Как и GNU Make: напишу мейкфайл, работает, а проблемы ненужных реализаций меня не волнуют.

Плюс надо понимать, что есть продукт одноразовый. Шеллскрипты и мейкфайлы — одноразовые. То есть применять их будешь только ты.

Иначе всё это затягивается до бесконечности.

a1batross ★★★★★
()

По дефолту пишу в скриптах #!/bin/sh, если есть необходимость усложнить и использовать башевскую функциональность - меняю на #!/bin/bash без зазрения совести.

При проблемах на каких-то платформах у пользователей, просто добавляю в CI нужную платформу и фикс в скрипт. Раз есть пользователи, значит нужно и тестирование.

Подход прост - быстро пишется скрипт для любой автоматизации, не надо заморачиваться. Позже, он без жалости выкинется, если не нужен, и останется и обрастет «мясом» если нужен. Практика предусмотреть всё, чего не знаешь, порочна и обладает свойством NP-полноты

Deleted
()

приходится писать bash скрипты

проверка наличия необходимых утилит в системе ... GNU sed

не нужно, это задача пакетного манагера или раздела «требования» в документации.

проверка что файловая система не read-only

set -e и let it fail погромче.

логирование

Если загадочно работает. Т.к. правильно работающая программа не должна выводить ненужной информации.

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

Если это на продажу, следует знать своего клиента. Если он способен/хочет понять 5 строк - лучше писать 5, он оценит простоту решения проблем на месте. Если нет - встраивать расширение мозгов клиента в скрипты - неразумно, т.к. требуемый объём быстро растёт с размером кода. Есть ли какой-то оптимум между этими точками и окупается ли его поиск? Вероятно нет, вариантов возникновения проблем больше, чем ты хочешь вообразить, и с ростом кода их увеличивается.

Cитуация может измениться, если «ленивых» потенциальных клиентов очень много. Однако тогда твои скрипты были бы на powershell/visual basic, т.ч. можно не рассматривать.

BTW, «совершенная» программа пишется дорого, и продаётся только 1 раз, а «приемлемая» - дёшево, и гарантирует необходимость сопровождения/обновления. Небольшой но постоянный поток денег проще для всех, чем большие качели.

DonkeyHot ★★★★★
()
Последнее исправление: DonkeyHot (всего исправлений: 1)

350

На питоне/перле/даже на c++ было бы короче, так что нет.

anonymous
()

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

x3al ★★★★★
()

Смотря кто вы - профессионал, или перегруженный моралью красноглаз?

Если первое - то вам нужно сделать быстро, чтобы работало и забыть. (проще написать другой скрипт из 5 строк. 5 + 5 меньше чем 350)

Если второе - то вы получаете от этого кайф и вас все равно не переубедить )

vaddd ★☆
()

Там было всё: проверка наличия необходимых утилит в системе, логирование, проверка что файловая система не read-only, даже проверка на то, что у меня именно GNU sed.

Везёт же некоторым. А я так и не научился писать скрипты с условными ветвлениями - не было необходимости.

iZEN ★★★★★
()

350(!)

Это фигня детская, здесь нет предмета обсуждения как такового. Вот например вещь от настоящих мужчин и только для них же. 4K хардкорнейшего state of art баша, не считая вспомогательных скриптов и обвеса в репе в сумме ещё на столько же.

А если и сейчас не страшно, то с другой стороны луны можно посмотреть вот эту няшку, 15K pure posix shell.

Поэтому не очень понятно что вы пытаетесь вымучить itt. Сделали проверки тулзов, ну хорошо. Я тоже делаю, таскаю копипастную функцию

CheckTools() {
    while [[ $1 ]]; do
        local tool=$1
        hash "$tool" 2>/dev/null || Fatal "$tool is required, but can not be found"
        shift
    done
}
Каноничные 5 строк, кстати. А кто-то не делает проверки. Ну это не очень хорошо, так как обидно если скрипт очень долго работает и потом вываливается из-за того что не хватило чего-то. Ну и ладно.

d_a ★★★★★
()

Башописцы обычно не переиспользуют, а делают свой велосипед.

anonymous
()

проверка что файловая система не read-only, даже проверка на то, что у меня именно GNU sed

Это всё конечно здорово, но что если какое-то условие не выполняется? Я бы просто 1.сделал бэкап, 2.запустил скрипт из 5 строк, 3.если что-то пошло не так - обзывал пользователя дебилом и восстанавил из бэкапа.

Ради 0.01% ситуаций раздувать код в сотни раз - это мягко говоря не рационально.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)

Ненормально. Почему бы не переписать на тот же python, у которого большая часть фич в std?

RazrFalcon ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.