LINUX.ORG.RU

А какие сейчас есть актуальные замены (da|ba|k|)sh для скриптов?

 , скриптинг


1

4

Пишу сейчас очередной sh-скрипт с кучей вызовов awk, grep и sed. В связи с чем задумался об альтернативах. Попытался сформировать список черт, которые делают sh до сих пор актуальным инструментом:

  • Возможность легко и просто скомпилировать под любой утюг.
  • Отсутствие развесистой библиотеки, которую интерпретатор таскает с собой, а также как следствие — нет слома совместимости между версиями библиотеки.
  • Минимальное время инициализации интерпретатора.
  • Малое потребление памяти.
  • Простой параллелизм через fork.
  • Возможность удобно и просто вызывать внешние команды и пайплайны команд.
  • Возможность прозрачно миксовать внешние команды и собственные функции. (В sh мы делаем command1 | command2, и это работает одинаково, независимо от того, являются ли эти команды собственными функциями или внешними командами.)

Если обобщить, то главным отличием sh от ЯП типа perl, ruby, python и т.п. является композиция программы как совокупности исполняемых модулей, запускаемых как отдельные процессы, в противовес композиции библиотечных модулей, слинкованных в единый процесс.

Главным минусом sh является то, что в нём не развиты средства работы с какими-либо структурами данных, кроме строк. Да и для самих строк средства не развиты.

То есть потециальная альтернатива sh должна обладать всем перечнем указанных черт, но дополнительно иметь развитые средства работы со структурами данных такими как списки, хэш-массивы и т.д.

★★★

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

сейчас можно и на жабе шелл-скрипты пейсать, стартует быстро, правда под оффтоп у меня такое не завелось в отличии от bash, но может там ядро надо было пересобрать прост

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

По-моему весь профит от того, что все эти sh sed awk grep позиксные и обязательно должны быть в /bin, полностью перечеркивается тем, какую же херню выдают остальные команды - без приседаний даже какой-нибудь сраный номер версии не вытянешь, чтобы можно было эту версию вынести в переменную или подставить в текст через $(...)

fumanchez
()

Смотрите, что происходит.

Один юзер предлагает Java (!!!) в качестве скриптового языка. Игнорируя вообще все пункты, перечисленные в ОП.

Я хотел сначала написать про то, что Java не соответствует пунктам «Минимальное время инициализации интерпретатора» и «Малое потребление памяти», но на самом деле она не соответствует никаким пунктам из списка.

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

Другой юзер предлагает nushell.

nushell — это огромный PowerShell-подобный комбайн, реализованный на Расте:

$ pacman -Si nushell
Репозиторий          : extra
Название             : nushell
Версия               : 0.94.1-1
Описание             : A new type of shell
Архитектура          : x86_64
URL                  : https://www.nushell.sh
Лицензии             : MIT
Группы               : Нет
Предоставляет        : Нет
Зависит от           : glibc  gcc-libs  libcrypto.so=3-64  libssl.so=3-64  zlib
Доп. зависимости     : Нет
Конфликтует с        : Нет
Заменяет             : Нет
Размер загрузки      : 20,15 MiB
Установленный размер : 104,19 MiB
Сборщик              : Caleb Maclennan <alerque@archlinux.org>
Дата сборки          : Пт 31 мая 2024 14:34:45
Проверен             : SHA-256  Подпись
$ pkgfile -l nushell | grep '[^/]$'
extra/nushell	/usr/bin/nu
extra/nushell	/usr/bin/nu_plugin_custom_values
extra/nushell	/usr/bin/nu_plugin_example
extra/nushell	/usr/bin/nu_plugin_formats
extra/nushell	/usr/bin/nu_plugin_gstat
extra/nushell	/usr/bin/nu_plugin_inc
extra/nushell	/usr/bin/nu_plugin_polars
extra/nushell	/usr/bin/nu_plugin_query
extra/nushell	/usr/bin/nu_plugin_stress_internals
extra/nushell	/usr/share/doc/nushell/README.md
extra/nushell	/usr/share/licenses/nushell/LICENSE

В качестве PowerShell-подобного комбайна nushell ориентирован на формирование собственной герметичной экосистемы, в рамках которой существуют его собственные уникальные инструменты с уникальным программным интерфейсом.

Это нечто противоположное идее легковесного клея для склеивания программы из существующих исполняемых модулей. То есть это буквально не «более фичастный аналог sh», а «анти-sh», «sh наоборот».

wandrien ★★★
() автор топика

Использую nushell как более шустрый заменитель zsh, плюс там вся shell концепция сильно изменена в сторону структур/данных, то есть это толком даже не bash, хотя некоторые классические команды там присутствуют и работают схожим образом.

Но nushell ещё слишком сырой, хватает багов, есть недоработки, при этом написан на rust.

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

Lua.

Много лет использую именно для «баш–скриптов». В том числе как голый интерпретатор с парсингом вывода нативных команд, (когда лень настраивать–подключать LFS или luaposix).

Подпадает буквально под все указанные хотелки. Очень шустрая работа со строками. Удобный универсальный тип данных — таблицы (гибрид массивов и key-value). Функции как first-class citizen. Параллелизм нативный, встроенный в язык. Тонны биндингов для каких угодно либ при необходимости. Легко интегрируется в сишный код.

anonymous
()

В борн шелл в основе лежит два режима парсинга - режим команд и режим ключевых слов, которые переключаются автоматически. Для них немного разные правила, касающиеся квотинга. Систем чтобы схема была перенесена 1-в-1 я не припомню. А из ближайшей альтернативы perl, правда он вышел из моды.

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

Тоже иногда на lua скрипты небольшие пишу, со строками моментами сильно проще работать чем в bash, ну и синтаксис сильно проще читать.

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

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

Ну поскольку ruby это по сути пофикшенный perl то почему нет. А что за элементы? Можно ли на них наколбасить отдельный режим разбора для вызова внеших команд без backticks?

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

Можно ли на них наколбасить отдельный режим разбора для вызова внеших команд без backticks?

Я где-то видел пример, где пайплайн записывался как

pipeLine ['ls'] | ['grep' 'blabla'] | ['wc' '-l']

Также можно попытаться применить для этого метод method_missing.

А сам я размышлял на тему того, что встроенных фич модуля open3 не вполне достаточно. Там нет возможности в качестве элемента пайплайна форкнуться, но не делать exec, а продолжить исполнять руби-код. А также вместо форка запустить Thread. Где-то у меня лежит набросок с такими фичами.

wandrien ★★★
() автор топика

sh-скрипт с кучей вызовов awk, grep и sed

Это pwsh. Для скриптов не обязательны нативные утилиты общего назначения, можно с ними, можно без, как удобней. Например ln удобней, чем New-Item, а grep, sed и awk уступают.

pwsh потребляет много ресурсов, но не требует особых зависимостей (gcc-libs glibc zlib), распаковал и пользуйся. Как вариант, есть пакет в AUR.

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

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

А в целом мои мысли на тему такого языка представляют вот что.

Первый вариант. Простой динамический ЯП с прототипным ООП, имеющий компактный встраиваемый интерпретатор. Комплектуется подходящей под задачу работы в качестве «клея» библиотекой и всё вместе зашивается в единый бинарь. Возможные кандидаты на роль такого ЯП: JS, Lua.

Второй вариант. ЯП с TCL-подобным синтаксисом, но с иной стандартной библиотекой. Библиотека должна быть максимально приближена к реалиям POSIX-совместимых систем и позволять напрямую обращаться к POSIX-фичам. То есть – «Сохранить идею sh, но переписать в синтаксисе TCL». Был один легковесный встраиваемый TCL-подобный интерпретатор, который можно взять за основу… забыл название. Не partcl, а еще более простой. Вроде на L начиналось название.

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

Он самый.

И это не «в качестве примера», а полноценная самостоятельная реализация языка. Вполне пригодная даже как repl — быстро что–нибудь посчитать или перекодировать.

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

perl на самом деле неплохой вариант – лучше, чем питон.

Код на perl не развалится через 5-10 лет, а вот код на питоне при выходе новой версии — запросто.

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

легковесный встраиваемый TCL-подобный интерпретатор

jimtcl?

динамический ЯП с прототипным ООП, имеющий компактный встраиваемый интерпретатор. Комплектуется подходящей под задачу работы в качестве «клея» библиотекой и всё вместе зашивается в единый бинарь.

Проектов в духе «Lua с батарейками» было не раз и не два. Те же penlight и luaforwindows. Но гибкость и компактность оригинала утрачивается. Не говоря уж о том, что это надо кому–то поддерживать и сопровождать.

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

Выглядит интересно. Откуда ты столько всего знаешь?

В Арче для сборки пакета опять половину репы хаскеля надо поставить для запуска pandoc-cli. Пуристы будут негодовать)

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

А… зачем?;-)

То есть ты все правильно пишешь, да - но если мы говорим про скриптоту, то для меня скриптота это «быстро сделал на коленке». Изучение любого нового ЯП/шелла в эту концепцию вписывается в единственном случае - ты ежедневно по несколько часов в день пишешь такую скриптоту. В таком случае ты скорее всего знаешь о своих хотелках и существующих возможностях гораздо больше тут присутствующих, хотя такой тред тебе конечно будет полезен в смысле выговориться, формализовать и систематизировать свои хотелки.

Во всех остальных случаях скриптоту надо писать на том что знаешь здесь и сейчас. Знаешь баш - берешь баш, знаешь питон/руби - берешь питон/руби. На современно железе как правило производительность скрипта некритична, а если критична - кучу запусков awk и пр. тоже не бесплатна вообще то…

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

Да, Python 3 до 2006 (вроде) был Python 3000, там много что обещали, и агитировали всех срочно переходить на последний, но благодаря некродистрам 2 прожил до 2019… Там главное отличие, что в двойке строки - это байты как в похапе, а в тройке как в попсе типа Java/JS «юникоде-кодепоинтс». Кучу моментов типа возвращение генераторов вместо списков map’ом можно опустить - это только олдфаки вспомнят… Ну вот много обещали, а ничего в принципе такого кардинального и нет (print еще без круглых скобок пейсать нельзя)

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

Ну там еще int/int–>float стал, синтаксис старый местами отвалился. Строки эти новые питонячьи я люто ненавижу потому шта появились еще bytes и иногда одно в другое надо гонять а то не работает.

Главное - при переходе от py2 к py3 они сломали обратную совместимость, но при этом не решили ни одной родовой травмы питона вроде разделения на изменяемые/неизменяемые объекты. За такое надо бить клавой по лицу ящитаю;-(

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

а если критична - кучу запусков awk и пр. тоже не бесплатна вообще то…

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

То есть вилка такая:

  • Если мы берём sh, у нас есть достаточно дешевые fork и exec, в том числе и exec с повторным входом в sh снова. Но самих этих fork и exec получается избыточно много.
  • Если мы берём «настоящий ЯП», то мы можем радикально сократить число лишних fork, но в то же время exec в самого себя становится сильно дороже, а использование пайплайнов – менее удобным.

Задачу можно решать с двух сторон.

  1. Брать крайне легковесный ЯП общего назначения, чтобы время инициализации интерпретатора снова стало дешевым. Выше предложили вариант с Lua.
  2. Брать узкоспециализированный ЯП под задачу. Выше тоже такой вариант предложили.

Как видишь, тема получается интересной.

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

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

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

Кстати сказать:

https://skarnet.org/software/execline/

execline is a (non-interactive) scripting language, like sh - but its syntax is quite different from a traditional shell syntax. The execlineb program is meant to be used as an interpreter for a text file; the other commands are essentially useful inside an execlineb script.

execline is as powerful as a shell: it features conditional loops, getopt-style option handling, filename globbing, and more. Meanwhile, its syntax is far more logical and predictable than the shell's syntax, and has no security issues. 

От разработчика системы супервизинга демонов s6.

wandrien ★★★
() автор топика