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 ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.