run

package module
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 13, 2026 License: MIT Imports: 14 Imported by: 0

README

Run


GoDoc Coverage Status

run

Библиотека 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

Функции 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.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Interface

type Interface interface {

	// StdInCh Канал с данными для потока STDIN. Канал должен быть закрыт там же где открывался.
	// Функция читает канал и передаёт процессу данные, до тех пор пока канал открыт и процесс запущен.
	StdInCh(ch <-chan []byte) Interface

	// StdIn Данные, отправляемые процессу в поток STDIN после запуска процесса.
	StdIn(buf []byte) Interface

	// StdOutCh Канал с данными полученными из процесса через поток STDOUT. Канал будет закрыт после завершения
	// процесса. Канал не создаётся, если функция не вызывалась.
	StdOutCh() (ret <-chan []byte)

	// StdOut Данные, полученные от процесса через поток STDOUT.
	StdOut() (ret []byte)

	// StdErrCh Канал с данными полученными из процесса через поток STDERR. Канал будет закрыт после завершения
	// процесса. Канал не создаётся, если функция не вызывалась.
	StdErrCh() (ret <-chan []byte)

	// StdErr Данные, полученные от процесса через поток STDERR.
	StdErr() (ret []byte)

	// WorkingDirectory Назначение директории выполнения приложения. По умолчанию - текущая директория.
	WorkingDirectory(dir string) Interface

	// Environment Переменные окружения, устанавливаемые для приложения. Переменные указываются как "КЛЮЧ=Значение".
	Environment(env ...string) Interface

	// Chroot Запускаемое приложение выполняется в режиме chroot в указанной директории.
	Chroot(dir string) Interface

	// Sudo Запускаемый процесс будет запущен от указанного пользователя и группы.
	// userID      - Идентификатор пользователя.
	// groupID     - Идентификатор группы.
	// noSetGroups - Флаг, указывающий не устанавливать дополнительные группы.
	// groups      - Массив идентификаторов дополнительных групп.
	Sudo(userID uint32, groupID uint32, noSetGroups bool, groups ...uint32) Interface

	// UserID Поиск идентификатора пользователя по названию пользователя.
	UserID(userName string) (ret uint32, err error)

	// GroupID Поиск идентификатора группы пользователя по названию группы.
	GroupID(groupName string) (ret uint32, err error)

	// Command Функция возвращает текущую запущенную команду.
	Command() (ret []string)

	// Debug Установка режима отладки.
	Debug(isDebug bool) Interface

	// Run Запуск приложения и возвращение из функции без ожидания завершения приложения.
	// Если передан контекст не равный nil, тогда прерывание через контекст завершает работу приложения аналогично
	// вызову функции Kill().
	Run(ctx context.Context, args ...string) Interface

	// RunWait Запуск приложения и ожидание завершения приложения.
	// Если передан контекст не равный nil, тогда прерывание через контекст завершает работу приложения аналогично
	// вызову функции Kill().
	RunWait(ctx context.Context, args ...string) (ret *os.ProcessState, err error)

	// Wait Ожидание завершения ранее запущенного приложения.
	Wait() (ret *os.ProcessState, err error)

	// LookPath Выполнение одноимённой утилиты exec.LookPath(), чтобы была под рукой.
	// Ошибку выполнения функции можно получить через Error().
	LookPath(proc string) (path string)

	// Pid Возвращает PID процесса. Если процесс не был запущен, возвращается -1.
	Pid() int

	// Signal Отправка сигнала ранее запущенному приложению.
	Signal(sig os.Signal) error

	// Kill Завершение ранее запущенного приложения.
	Kill() error

	// Release Освобождение всех ресурсов запущенного приложения.
	// Release необходимо выполнять только в случае если Wait() не работает.
	Release() error

	// Reset Завершение приложения, если оно было запущено, сброс всех настроек и подготовка пакета для
	// повторного использования.
	Reset() Interface

	// Error Ошибка, возникшая в функции не возвращающей ошибки.
	Error() error
}

Interface Интерфейс пакета.

func New

func New() Interface

New Конструктор объекта сущности пакета.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL