Библиотека Golang предоставляющая интерфейс к стандартным пакетам go, для решения задач связанных с запуском и взаимодействием с запущенными приложениями.
run — это обёртка над стандартными пакетами os, os/exec и context, решающая задачи запуска
внешних приложений и обмена данными с ними через стандартные потоки ввода-вывода (STDIN, STDOUT,
STDERR). Пакет берёт на себя управление вспомогательными горутинами и каналами, обеспечивает
гарантированную доставку данных и корректное освобождение ресурсов после завершения процесса.
- Запуск приложений с ожиданием завершения и без ожидания;
- Обмен данными через STDIN, STDOUT, STDERR, как через буферы, так и через каналы;
- Передача больших объёмов данных без блокировки вспомогательных горутин;
- Завершение запущенного приложения через контекст;
- Настройка рабочей директории, переменных окружения, chroot, пользователя и группы;
- Отправка сигналов запущенному приложению, принудительное завершение;
- Сброс состояния и повторное использование объекта одной функцией
Reset(); - Нулевые зависимости, режим отладки с выводом внутренних сообщений.
- Go 1.19 или новее.
go get -u github.com/webnice/runПодключение:
import (
"github.com/webnice/run"
)NONE
obj := run.New()
if _, err := obj.RunWait(nil, "echo", "привет"); err != nil {
log.Fatalf("запуск приложения прерван ошибкой: %s", err)
}
log.Printf("команда: %v, завершена успешно", obj.Command())Функции StdIn, StdOut, StdErr работают с буферами: функции StdOut и StdErr блокируются
до момента получения всех данных, в то время как в канал, открытый функциями StdInCh, StdOutCh,
StdErrCh, данные поступают без задержки.
obj := run.New()
obj.StdIn([]byte("тестовые данные\n"))
if _, err := obj.RunWait(nil, "head", "-n", "1"); err != nil {
log.Fatalf("запуск приложения прерван ошибкой: %s", err)
}
log.Printf("получено из STDOUT: %q", obj.StdOut())obj := run.New()
chIn := make(chan []byte)
obj.StdInCh(chIn)
chOut := obj.StdOutCh()
go func() {
chIn <- []byte("тестовые данные\n")
close(chIn)
}()
if _, err := obj.RunWait(nil, "head", "-n", "1"); err != nil {
log.Fatalf("запуск приложения прерван ошибкой: %s", err)
}
for data := range chOut {
log.Printf("получено из STDOUT: %q", data)
}Если передан контекст не равный nil, тогда прерывание через контекст завершает работу приложения
аналогично вызову функции Kill().
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
obj := run.New()
if _, err := obj.RunWait(ctx, "sleep", "60"); err != nil {
log.Fatalf("запуск приложения прерван ошибкой: %s", err)
}obj := run.New()
if obj.Run(nil, "sleep", "60").Error() != nil {
log.Fatalf("запуск приложения прерван ошибкой: %s", obj.Error())
}
log.Printf("процесс запущен, PID: %d", obj.Pid())
if err := obj.Signal(syscall.SIGTERM); err != nil {
log.Fatalf("передача сигнала прервана ошибкой: %s", err)
}
if _, err := obj.Wait(); err != nil {
log.Fatalf("ожидание завершения прервано ошибкой: %s", err)
}obj := run.New()
obj.
WorkingDirectory("/tmp").
Environment("KEY1=Value1", "KEY2=Value2").
Chroot("/").
Sudo(0, 0, true)
if _, err := obj.RunWait(nil, "echo", "привет"); err != nil {
log.Fatalf("запуск приложения прерван ошибкой: %s", err)
}Идентификаторы пользователя и группы можно найти по их названиям:
uid, err := run.New().UserID("www-data")
if err != nil {
log.Fatalf("поиск пользователя прерван ошибкой: %s", err)
}Функция Reset() завершает приложение, если оно было запущено, сбрасывает все настройки и
подготавливает объект для повторного использования.
obj := run.New()
for i := 0; i < 10; i++ {
if _, err := obj.RunWait(nil, "echo", "привет"); err != nil {
log.Fatalf("запуск приложения прерван ошибкой: %s", err)
}
obj.Reset()
}Конструктор New() возвращает объект удовлетворяющий интерфейсу run.Interface:
StdInCh,StdIn,StdOutCh,StdOut,StdErrCh,StdErr— обмен данными с процессом;WorkingDirectory,Environment,Chroot,Sudo— настройки запуска приложения;UserID,GroupID— поиск идентификаторов пользователя и группы по их названиям;Command— возвращает текущую запущенную команду;Debug— включение режима отладки;Run,RunWait,Wait— запуск и ожидание завершения приложения;LookPath— поиск исполняемого файла программы;Pid,Signal,Kill,Release— управление запущенным процессом;Reset— сброс состояния и подготовка к повторному использованию;Error— ошибка, возникшая в функции не возвращающей ошибку.
Полное описание методов интерфейса доступно в документации пакета: https://pkg.go.dev/github.com/webnice/run.
# Стандартный прогон с покрытием.
go test -cover ./...
# Прогон через Makefile (агрегированный профиль покрытия в coverage.log).
make test© WEB NICE, распространяется под лицензией MIT.