LINUX.ORG.RU

Lua Shell

 , , ,


2

5

Контест этого топика: Леннарт теперь до эмуляторов терминала добрался (комментарий)

@EXL:

Лучше бы Lennart взялся за Bash.

@wandrien:

Там только выкинуть целиком. Я вот хочу попытаться для lua сделать обвязку для скриптинга уровня оболочки. Подобные либы на Lua есть, но качество и объем фич мне не нравится. Надо лучше. Тебе бы был интересен такой проект?


Итак, вот моя идея в общих чертах. Составные части, на которых основываться:

https://github.com/BanceDev/lush
Низкое качество сборочного скрипта. Вероятно, и кода тоже. Интересует идея в первую очередь.

https://github.com/mna/luashell
Ключевое, что нам нужно. Взять за основу. Но:

  • Нужны полнофункциональные средства перенаправления ввода-вывода, заменить эту часть API. Под капотом, вероятно. придётся делать полноценную обработку fork - настройка процесса - exec.
  • test() должен быть вменяемый, а не парсить строку по пробелам. Просто алиас для sh.cmd("test", ...).exec()
  • Форк процесса без exec в качестве элемента пайплайна на уровне API
  • Как расширение предыдущего - обёртка а ля sh.echo("text").

В качестве базового API взять https://25thandclement.com/~william/projects/lunix.html вместо https://github.com/luaposix/luaposix

Также рассмотреть для включения и/или как источник идей:


Общая идея:

  • Lua + lunix — получаем возможность писать на Луа «приложения как на Си под libc».
  • Сверху на это - форкнутый и допиленный luashell. Это ключевое.
  • Далее QoL вещи: lua-path, argparse, функции для парсинга и форматирвоания времени, функции для JSON.
  • Далее - разработать интерактивный режим для использования в качестве командной оболочки.

Продукт компилируется в статический бинарь с musl и/или cosmopolitan libc и получаем «вечный» shell. При этом весьма компактный.

★★★

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

Нафиг тебе awk, если будет полноценная lua в наличии?

Смешно звучит: «полноценная lua». Это с её убогими недорегулярками, которые они в доках называют паттернами?

debugger ★★★★★
()

А что насчёт nushell? Там пытались что-то сделать.

Ну и для скриптов можно на bun посмотреть, там сразу есть хорошая интеграция shell. В результате получается базовый язык не lua, а typescript, в котором всё-таки побольше сахара. Ну и сразу куча интеграций из bun: sql, сеть, redis, подключение данных по import-ам, ffi и т.д.

Может даже на основе bun можно какой-то интерактивный шелл сделать

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

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

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

#!/usr/bin/env bb
(require '[babashka.cli :as cli]
         '[babashka.fs :as fs])

(defn dir-exists?
  [path]
  (fs/directory? path))

(defn show-help
  [spec]
  (cli/format-opts (merge spec {:order (vec (keys (:spec spec)))})))

(def cli-spec
  {:spec
   {:num {:coerce :long
          :desc "Number of some items"
          :alias :n                     ; adds -n alias for --num
          :validate pos?                ; tests if supplied --num >0
          :require true}                ; --num,-n is required
    :dir {:desc "Directory name to do stuff"
          :alias :d
          :validate dir-exists?}        ; tests if --dir exists
    :flag {:coerce :boolean             ; defines a boolean flag
           :desc "I am just a flag"}}
   :error-fn                           ; a function to handle errors
   (fn [{:keys [spec type cause msg option] :as data}]
     (when (= :org.babashka/cli type)
       (case cause
         :require
         (println
           (format "Missing required argument: %s\n" option))
         :validate
         (println
           (format "%s does not exist!\n" msg)))))})

(defn -main
  [args]
  (let [opts (cli/parse-opts args cli-spec)]
    (if (or (:help opts) (:h opts))
      (println (show-help cli-spec))
      (println "Here are your cli args!:" opts))))

(-main *command-line-args*)

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

А если для того же результата нужно сотню строк шелловой лапши пилить (при том что исходная задача вся целиком укладывается в 15), то и ну его нафиг.

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

убогими недорегулярками

Значит надо положить в состав неубогие регулярки.

А не вот это, когда говорим «awk», читаем «gawk» и надеемся, что на машине юзера подходящая версия.

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

Надо на лиспе же.

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

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

Очень мило. А вот такое можешь?

<file.gz gunzip | tee >(sha1sum > file.sha1) | xz > file.xz
legolegs ★★★★★
()
Ответ на: комментарий от legolegs

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

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

Баш жив только благодаря формальной POSIX-совместимости и Столлманоугодной лицензии. Аналоги его уже во многом переплюнули.

В целом, конвейеры – удачное решение, соглашусь.

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

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

Держи мнемонику хотя бы по поводу стороны обрезания: # расположен левее на клавиатуре, чем %, соответственно, обрезает слева. %, соответственно, справа.

А потом ты узнаешь, что в двух местах забыл сраные кавычки. Именно там программа и грохнулась.

От этого помог бы shellcheck.

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

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

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

Ну если извернуться, то на луашке вполне можно написать будет например так(возможно есть способы лучше):

mke2fs { _E, lazy_itable_init=0, lazy_journal_init=0, _L, "mylabel", "/dev/sdd1" }

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

AKonia ★★★
()
Последнее исправление: AKonia (всего исправлений: 2)
Ответ на: комментарий от papin-aziat
$ cat 1.sh 
f1() {
    echo "a_b c_d"
}

f2() {
    echo "args:"
    while test $# -gt 0 ; do
        echo "=> $1"
        shift
    done
}

IFS=' '
f2 `f1`
IFS='_'
f2 `f1`
IFS=''
f2 `f1`
$ sh 1.sh 
args:
=> a_b
=> c_d
args:
=> a
=> b c
=> d
args:
=> a_b c_d
wandrien ★★★
() автор топика
Ответ на: комментарий от wandrien

Вы куда-то не в ту степь ушли.

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

$ a="$(printf '%s\n' "$(echo foo bar)")"; printf '[%s]\n' "$a"
[foo bar]
$ a=$(printf '%s\n' "$(echo foo bar)"); printf '[%s]\n' "$a"
[foo bar]
b='herp derp'
$ a=$b; printf '[%s]\n' "$a"
[herp derp]
$ a="$b"; printf '[%s]\n' "$a"
[herp derp]
$ a="hippety hoppety"; printf '[%s]\n' "$a"
[hippety hoppety]
$ a=hippety hoppety; printf '[%s]\n' "$a"
bash: hoppety: команда не найдена
legolegs ★★★★★
()
Ответ на: комментарий от papin-aziat

printf '%s\n' $(echo one two three) vs printf '%s\n' "$(echo one two three)", потом поменять IFS= и попробовать еще раз.

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

Вот да, баш не лезет при передачи значения переменной подстановками.

papin-aziat ★★★★★
()
Ответ на: комментарий от wandrien

Привычка ставить кавычки везде.

Интересно, хорошая ли это привычка!?

Кто-то выше писал, что стал юзать баш, когда появился ИИ. Я — тоже, и он, собака, везде всё кавычит. Почему? Потому что так делают люди. В результате, чтобы понять как всё это на самом деле работает, приходится постоянно экспериментировать.

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

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

ИИ этот ваш тоже документацию не читает? Насчет книг, есть Bash Cookbook, мне понравилось. Люблю такой формат без лишней воды строго по делу.

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

Bash Cookbook

Да, надо почитать когда-нибудь.

ИИ этот ваш тоже документацию не читает?

Читает, да что толку, он же не размышляет над прочитанным 😁

papin-aziat ★★★★★
()
Ответ на: комментарий от shkolnick-kun

Микроридлайн ремастер же!

А ещё есть bestline от Justine Tunney:

Library for interactive pseudoteletypewriter command sessions using ANSI Standard X3.64 control sequences.

This is a single-file, no-dependencies C or C++ library that makes it as easy as possible to display a command prompt that asks the user for input. It supports Emacs editing shortcuts, history search, completion / hint callback, and UTF-8 editing under a BSD-2 license.

Bestline is a fork of linenoise (a popular GNU Readline alternative) that fixes its bugs and adds the missing features while reducing binary footprint (surprisingly) by removing bloated dependencies, which means you can finally have a permissively-licensed command prompt w/ a 38kb footprint that’s nearly as good as GNU Readline.

Она «из коробки» входит в muon.

dataman ★★★★★
()
Ответ на: комментарий от papin-aziat

Привычка ставить кавычки везде.

Интересно, хорошая ли это привычка!?

ИМХО, не такая уж и плохая. Но лучше, конечно, понимать в каждом конкретном случае.

Пробуйте свои скрипты с параметрами / именами файлов содержащими пробелы и сами убедитесь.

LLM-9000
()
Ответ на: комментарий от LLM-9000

Дык пробую постоянно и в результате кавычек остаётся не так уж много — обычно нужны только в подстановках, которые становятся аргументами для программ или функций (это понятно, так как баш сначала вычисляет переменную, а потом разбивает на слова). Кстати, это опять же не всегда надо делать, если качество данных известно как в случае выше, где идут имена иконок, — кто ж в здравом уме будет именовать их через пробел?!

papin-aziat ★★★★★
()
Ответ на: комментарий от wandrien
get_icon_name_for_file() {
    check_tool GIO || return 1
    [[ -n $1 ]] || return 1
    [[ -e $1 ]] || return 1
    ( # force "local" variables
        icon_line=$($GIO info -a standard::icon "$1" | grep standard::icon)
        icon_line=${icon_line##*: }
        icon_line=${icon_line%%,*}
        printf %s $icon_line
    )
}

Почему не будет работать?

papin-aziat ★★★★★
()
Ответ на: комментарий от wandrien

Вроде про баш разговор. Ладно, в test придётся оставить. Кстати, так и выглядеть будет лучше, как ты любишь, консистентно 🙂

И всё же, ты ведь сэкономил кавычек на регулярном выражении, потому что знаешь, что там нет метасимволов, да? Почему так же не делать с башем?

papin-aziat ★★★★★
()
Последнее исправление: papin-aziat (всего исправлений: 1)
Ответ на: комментарий от LLM-9000

Кстати, меня вот больше всего расстраивает в шелл-программировании, что баш постоянно проверяет рабочую директорию на предмет чего-нибудь оттуда подставить, а юзерские скрипты по умолчанию сидят в хомяке, где может быть что угодно. Получается, чтобы это вычеркнуть, надо менять рабочую на пустую песочницу что ли!?

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

Вы имеете ввиду pathname expansion / globbing? Тут скорее требуется внимательность к наличию символов *, ?, [ во входных данных. Иначе, да, возможны грабли любых калибров и перемещение в другую директорию не особо поможет.

LLM-9000
()
Ответ на: комментарий от yars068

Погоди, ты ведь про каталог script и в скрипты из ~/bin начинать с cd ~/.bin/script?

Хотя из bin наверное смотрят в bin. Я с терминалом перепутал 😁

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

Это ничего не меняет тогда, у меня там куча всего (как наверное у любого линуксоида).

Ну, и добавить его в PATH юзеру.

В шапкодистрах так по умолчанию.

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

Почему?

Если речь действительно о неучтённых подстановках (expansions), то это ведь не так и важно какие имена файлов bash увидит, из домашней директории или из отдельной или даже пустую строку там, где ожидался специальный символ.

Мы, выходит, уже обсуждаем предположение, с конкретным примером было бы понятнее что идёт не так.

LLM-9000
()
Ответ на: комментарий от papin-aziat

Но никто не запрещает внутрь каталога положить ещё каталог, а в него уже собрать скрипты и также его в PATH добавить… Только незачем.

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

А смысл, если скрипты опять будут сидеть а каталоге с кучей файлов?

papin-aziat ★★★★★
()
Ответ на: комментарий от wandrien

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

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

Просто оставьте шеллу шеллово — выполнение команд и их комбинирование в более сложные команды, а сами команды пешите на чём угодно, только не на шелле. Бабашку тут уже рекламировали %)

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

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

То, что у нас всех массово синдром утёнка относительно sh, не делает sh хорошим языком.

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

Да, или можно просто сломать конструкцию [] для баша — типа foo[bar\].

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

papin-aziat ★★★★★
()
Последнее исправление: papin-aziat (всего исправлений: 1)
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.