| Translations Blog |

Transparent PNG

Оболочка Имеет Четвертое Качество

Перевод статьи - Shell Has a Forth-like Quality

Автор(ы) - Andy Chu

Источник оригинальной статьи:

http://www.oilshell.org/blog/2017/01/13.html

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

Я понимаю, что не сделал многого из того, о чем упоминал во втором предложении этого блога: объясните, почему оболочка Unix интересна. Отчасти это связано с тем, что почти никто не ставил под сомнение этот проект — похоже, программисты действительно хотят иметь лучшую оболочку.

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

Настройка демонов Unix

Systemd имеет заявленную цель замены сценариев оболочки в процессе загрузки системы Linux.

В ответ на еще одну тему о компромиссах дизайна systemd agumonkey он заявил, что shell не обладает достаточной силой абстракции. Вместо этого он предложил шепелявую систему конфигурации:

(->
    (path "/usr/bin/some-service" "arg0" ...)
    (wrap :pre (lambda () ...)
          :post (lambda () ..))
    (retry 5)
    ...
    (timeout 5))

Я отметил, что shell уже поддерживает этот вид программирования более высокого порядка. Например, вот функция, которая принимает команду и пробует ее пять раз:

retry() {
  local n=$1
  shift
  for i in $(seq $n); do
    "$@"
  done
}

Его можно использовать так:

$ retry 5 hello-sleep 0.1
hello
hello
hello
hello
hello

Здесь мы передаем целое число 5 и фрагмент кода hello-sleep 0.1 в функцию retry. Поскольку retry попытка обрабатывает код как данные, вы можете назвать его функцией высшего порядка.

Если пойти дальше, то мы можем составить нашу retry функцию с двоичным таймаутом coreutils, добавив еще два слова:

$ timeout 0.3 $0 retry 5 hello-sleep 0.1
hello
hello
hello  # killed after 0.3 seconds

(Запускаемый код доступен в forth-подобном каталоге репозитория oilshell/blog-code repository).

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

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

Оболочка не имеет неявного стека, но равномерное представление слов в argv массиве и "сращивание" с "$@" ними приводит к тому, что код кажется похожим.

В отличие от этого, этот механизм не является идиоматическим в Python или JavaScript. Я попробовал портировать demo.shна Python с помощью demo.py, и это вроде как работает, если вы пишете все функции, как f(*args). Но это идет вразрез с принципами экосистемы. В этих языках функции и аргументы трактуются по-разному с синтаксической и семантической точек зрения.

 

daemontools и Bernstein Chaining

В книге "Искусство программирования Unix", представляющей собой великолепное изложение философии Unix, Эрик Реймонд называет эту технику цепочкой Бернштейна.

Бернштейн использует эту технику оболочки в таких программах, как qmail и daemontools, чтобы следовать принципу наименьших привилегий.

В отличие от systemddaemontools init - это инструментарий Unix, который опирается на идиому небольших C-программ, составленных с помощью shell-скриптовПразднование daemontools хорошо обосновывает это и показывает примеры. Вот выдержка , в которой используется бернштейновская цепочка setuidgidиsoftlimit, а также встроеннаяexec:

# change to the user 'sample', and then limit the stack segment
# to 2048 bytes, the number of open file descriptors to 3, and
# the number of processes to 1:
exec setuidgid sample \
     softlimit -n 2048 -o 3 -p 1 \
     some-small-daemon -n

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

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

Вывод

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

Поскольку я пишу оболочку, неудивительно, что я предвзято отношусь к стилю daemontools. Но systemd справедливо критикует шелл-скрипты. Язык имеет много проблем, одним из примеров которых является синтаксис массива.

С другой стороны, я не удивлюсь, если конфигурация systemd случайно станет полной по Тьюрингу, как это сделали shell и make.

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

Приложение: Команды, которые составляют

Вот список инструментов, которые могут быть составлены таким образом:

Это встроенные оболочки, которые составляют:

Обновления (2017/1/24)