С тех пор, как была анонсирована система плагинов, я хотел создать среду для создания интерактивных программ командной оболочки, в которых команды реализуются с использованием плагинов Go (идея возникла из моего старого Java-проекта). Итак, я создал Gosh (оболочку Go).

Гоша - https://github.com/vladimirvivien/gosh

Gosh (оболочка Go) использует программу оболочки драйвера для загрузки подключаемых модулей команд во время выполнения. Плагины реализуют обработчики, которые реагируют на ввод командной строки в командной строке. Когда пользователь вводит команду, драйвер отправляет зарегистрированный плагин для обработки команды.

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

Гоша Дизайн

Когда программа оболочки Gosh запускается, она загружает файлы плагинов Go (*_command.so) из указанного каталога. Каждый плагин регистрируется с именем команд, которые он обрабатывает. После регистрации команды программа отображает приглашение gosh>, готовое для ввода команд.

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

Плагины команд Gosh реализуют интерфейс Command, который использует метод Exec для определения поведения команды.

type Command interface {
	Name() string
	Usage() string
	ShortDesc() string
	LongDesc() string
	Exec(context.Context, []string) (context.Context, error)
}

Подключаемый модуль команды должен экспортировать переменный символ типа Commands, который предоставляет реестр доступных Command реализованных.

type Commands interface {
  ...
	Registry() map[string]Command
}

См. Gosh / plugins / testcmd.go для примера подключаемого модуля команды Gosh.

Как это работает

Прежде чем вы попробуете Гоша, ознакомьтесь с предварительными условиями плагина Go:

  • Go версия 1.8
  • ОС Linux (пока)

Загрузите или клонируйте репозиторий Gosh (см. Ссылку выше). Для быстрого старта запустите следующее:

go run shell/gosh.go

Вы получите следующий вывод, указывающий, что ожидаемых команд нет:

                        888
                        888
                        888
 .d88b.  .d88b. .d8888b 88888b.
d88P"88bd88""88b88K     888 "88b
888  888888  888"Y8888b.888  888
Y88b 888Y88..88P     X88888  888
 "Y88888 "Y88P"  88888P'888  888
     888
Y8b d88P
 "Y88P"

No commands found

Затем выйдите из оболочки gosh (Ctrl-C) и скомпилируйте пример подключаемого модуля, который поставляется с исходным кодом.

go build -buildmode=plugin   \
  -o plugins/sys_command.so  \
  plugins/syscmd.go

Предыдущая команда скомпилирует plugins/syscmd.go и выведет общий объект plugins/sys_command.so в виде файла плагина Go. Этот плагин реализует несколько системных команд, включая help для отображения справочных сообщений и exit, который существует в оболочке REPL.

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

> ls -lh plugins/
total 3.2M
-rw-rw-r-- 1  4.5K Mar 19 18:23 syscmd.go
-rw-rw-r-- 1  3.2M Mar 19 19:14 sys_command.so
-rw-rw-r-- 1  1.4K Mar 19 18:23 testcmd.go

Теперь, когда gosh перезапущен, он будет динамически загружать команды, которые находит в каталоге ./plugins:

> go run shell/gosh.go
...
Loaded 4 command(s)...
Type help for available commands
gosh>

Как указано в выходных данных выше, при вводе help будут перечислены все доступные команды в оболочке:

gosh> help
help: prints help information for other commands.
Available commands
------------------
      prompt:	sets a new shell prompt
         sys:	sets a new shell prompt
        help:	prints help information for other commands.
        exit:	exits the interactive shell immediately
Use "help <command-name>" for detail about the specified command

Затем мы можем ввести команду sys для отображения системной информации и exit, когда закончите.

gosh> sys
System Info
-----------
         arc: amd64
          os: linux
        cpus: 4
         mem: 1740800
    hostname: ubuntu
    pagesize: 4096
     groupid: 1000
      userid: 1000
         pid: 31483
        exec: /tmp/go-build118078117/command-line-arguments/_obj/exe/gosh
gosh>  exit
exiting...

Если вы заинтересованы в реализации вашего собственного подключаемого модуля команды Gosh, проверьте gosh / plugins / testcmd.go. Он используется для тестирования, но реализует все методы, необходимые для рабочего командного плагина.

Заключение

Гоша демонстрирует, что можно сделать с новой системой плагинов Go. Программа предоставляет платформу для создания мощных интерактивных командных оболочек с использованием масштабируемой и подключаемой конструкции. Надеюсь, что вы сочтете Gosh полезным и создадите на его основе свою собственную систему командной оболочки. Кроме того, я надеюсь, что вы используете это как модель для создания масштабируемых модульных программ на Go!

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

Также не забудьте проверить мою книгу о Go под названием Learning Go Programming от Packt Publishing.