Это многостраничный печатный вид этого раздела. Нажмите что бы печатать.

Вернуться к обычному просмотру страницы.

Пакет os языка программирования Go

Пакет os предоставляет платформонезависимый интерфейс к функциональности операционной системы.

Пакет os предоставляет платформонезависимый интерфейс к функциональности операционной системы. Дизайн Unix-подобный, хотя обработка ошибок Go-подобная; неудачные вызовы возвращают значения типа error, а не номера ошибок. Часто в ошибке содержится больше информации. Например, если вызов, принимающий имя файла, не работает, например Open или Stat, ошибка будет включать имя файла, который не работает, и будет иметь тип *PathError, который может быть распакован для получения дополнительной информации.

Интерфейс os должен быть единообразным для всех операционных систем. Функции, которые не являются общедоступными, представлены в специфическом для системы пакете syscall.

Приведем простой пример: открытие файла и чтение его части.

file, err := os.Open("file.go") // For read access.
if err != nil {
	log.Fatal(err)
}

Если открытие завершится неудачей, строка ошибки будет иметь понятный вид, например

open file.go: no such file or directory

Затем данные файла могут быть считаны в виде фрагмента байтов. Команды Read и Write берут количество байтов из длины фрагмента аргумента.

data := make([]byte, 100)
count, err := file.Read(data)
if err != nil {
log.Fatal(err)
}
fmt.Printf("read %d bytes: %q\n", count, data[:count])

Concurrency (Параллелизм)

Методы File соответствуют операциям файловой системы. Все они безопасны для одновременного использования. Максимальное количество одновременных операций над файлом может быть ограничено ОС или системой. Это число должно быть большим, но его превышение может снизить производительность или вызвать другие проблемы.

Константы


const (
    // Должно быть указано ровно одно из значений O_RDONLY, O_WRONLY или O_RDWR.
    O_RDONLY int = syscall.O_RDONLY // открыть файл только для чтения.
    O_WRONLY int = syscall.O_WRONLY // открыть файл только для записи.
	O_RDWR   int = syscall.O_RDWR   // открыть файл для чтения и записи.
    // Остальные значения могут быть объединены с помощью оператора OR для управления поведением.
    O_APPEND int = syscall.O_APPEND // добавлять данные в файл при записи.
    O_CREATE int = syscall.O_CREAT  // создать новый файл, если его нет.
	O_EXCL   int = syscall.O_EXCL   // используется с O_CREATE, файл не должен существовать.
    O_SYNC   int = syscall.O_SYNC   // открыть для синхронного ввода-вывода.
    O_TRUNC  int = syscall.O_TRUNC  // усечь обычный файл с правом записи при открытии.
)

Флаги для OpenFile, оборачивающие флаги базовой системы. Не все флаги могут быть реализованы в данной системе.

Просмотреть исходный код const ( PathSeparator = „/“ // разделитель путей, специфичный для ОС PathListSeparator = „:“ // разделитель списка путей, специфичный для ОС)

const (
    // Одиночные буквы являются аббревиатурами,
    // используемыми для форматирования методом String.
	ModeDir        = fs.ModeDir        // d: каталог
    ModeAppend     = fs.ModeAppend     // a: только добавление
    ModeExclusive  = fs.ModeExclusive  // l: исключительное использование
    ModeTemporary  = fs.ModeTemporary  // T: временный файл; только Plan 9
    ModeSymlink    = fs.ModeSymlink    // L: символическая ссылка
	ModeDevice     = fs.ModeDevice     // D: файл устройства
    ModeNamedPipe  = fs.ModeNamedPipe  // p: именованный канал (FIFO)
    ModeSocket     = fs.ModeSocket     // S: сокет домена Unix
    ModeSetuid     = fs.ModeSetuid     // u: setuid
	ModeSetgid     = fs.ModeSetgid     // g: setgid
    ModeCharDevice = fs.ModeCharDevice // c: символьное устройство Unix, когда установлен ModeDevice
    ModeSticky     = fs.ModeSticky     // t: sticky
    ModeIrregular  = fs.ModeIrregular  // ?: нерегулярный файл; ничего больше не известно об этом файле

	// Маска для битов типа. Для обычных файлов не будет установлено ничего.
    ModeType = fs.ModeType

    ModePerm = fs.ModePerm // Биты разрешений Unix, 0o777
	)

Определенные биты режима файла являются наиболее значимыми битами FileMode. Девять наименее значимых битов являются стандартными разрешениями Unix rwxrwxrwx. Значения этих битов следует рассматривать как часть общедоступного API и могут использоваться в протоколах передачи данных или представлениях диска: их нельзя изменять, хотя могут быть добавлены новые биты.

const DevNull = "/dev/null"

DevNull — это имя «нулевого устройства» операционной системы. В Unix-подобных системах оно имеет вид «/dev/null», в Windows — «NUL».

Переменные

var (
    // ErrInvalid указывает на недействительный аргумент.
    // Методы File возвращают эту ошибку, когда получатель равен nil.
    ErrInvalid = fs.ErrInvalid // «недействительный аргумент»

    ErrPermission = fs.ErrPermission // «разрешение отказано»
    ErrExist      = fs.ErrExist      // «файл уже существует»
	ErrNotExist   = fs.ErrNotExist   // «файл не существует»
    ErrClosed     = fs.ErrClosed     // «файл уже закрыт»

    ErrNoDeadline       = errNoDeadline()       // «тип файла не поддерживает срок»
    ErrDeadlineExceeded = errDeadlineExceeded() // «тайм-аут ввода-вывода»
)

Портативные аналоги некоторых распространенных ошибок системных вызовов.

Ошибки, возвращаемые из этого пакета, можно проверить на наличие этих ошибок с помощью errors.Is.

var (
    Stdin  = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
    Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
	Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr"))

Stdin, Stdout и Stderr — открытые файлы, указывающие на дескрипторы стандартного ввода, стандартного вывода и стандартных ошибок.

Обратите внимание, что среда выполнения Go записывает в стандартный файл ошибок сообщения о паниках и сбоях; закрытие Stderr может привести к тому, что эти сообщения будут отправляться в другое место, например в файл, открытый позже.

var Args []string

Args содержит аргументы командной строки, начиная с имени программы.

var ErrProcessDone = errors.New("os: process already finished")

ErrProcessDone указывает, что процесс завершен.

1 - Описание функций пакета os

Основные функции пакета os языка программирования GO

func Chdir

func Chdir(dir string) error

Chdir изменяет текущий рабочий каталог на указанный каталог. Если произошла ошибка, она будет типа *PathError.

func Chmod

func Chmod(name string, mode FileMode) error

Chmod изменяет режим указанного файла на mode. Если файл является символической ссылкой, то изменяется режим цели ссылки. Если произошла ошибка, то она будет типа *PathError.

В зависимости от операционной системы используется разный поднабор битов режима.

В Unix используются биты разрешений режима ModeSetuid, ModeSetgid и ModeSticky.

В Windows используется только бит 0o200 (доступ на запись для владельца) режима; он контролирует, установлен ли или снят атрибут «только для чтения» файла. Остальные биты в настоящее время не используются. Для совместимости с Go 1.12 и более ранними версиями используйте режим, отличный от нуля. Используйте режим 0o400 для файла, доступного только для чтения, и 0o600 для файла, доступного для чтения и записи.

В Plan 9 используются биты разрешений режима ModeAppend, ModeExclusive и ModeTemporary.

Пример
package main

import (
	"log"
	"os"
)

func main() {
	if err := os.Chmod("some-filename", 0644); err != nil {
		log.Fatal(err)
	}
}

func Chown

func Chown(name string, uid, gid int) error

Chown изменяет числовые значения uid и gid указанного файла. Если файл является символической ссылкой, он изменяет uid и gid цели ссылки. uid или gid равные -1 означают, что это значение не изменяется. Если происходит ошибка, она будет типа *PathError.

В Windows или Plan 9 Chown всегда возвращает ошибку syscall.EWINDOWS или EPLAN9, обернутую в *PathError.

func Chtimes

func Chtimes(name string, atime time.Time, mtime time.Time) error

Chtimes изменяет время доступа и изменения указанного файла, аналогично функциям Unix utime() или utimes(). Нулевое значение time.Time оставит время соответствующего файла без изменений.

Базовая файловая система может усечь или округлить значения до менее точной единицы времени. Если произошла ошибка, она будет типа *PathError.

Пример
package main

import (
	"log"
	"os"
	"time"
)

func main() {
	mtime := time.Date(2006, time.February, 1, 3, 4, 5, 0, time.UTC)
	atime := time.Date(2007, time.March, 2, 4, 5, 6, 0, time.UTC)
	if err := os.Chtimes("some-filename", atime, mtime); err != nil {
		log.Fatal(err)
	}
}

func Clearenv

func Clearenv()

Clearenv удаляет все переменные окружения.

func CopyFS

func CopyFS(dir string, fsys fs.FS) error

CopyFS копирует файловую систему fsys в каталог dir, создавая dir при необходимости.

Файлы создаются с режимом 0o666 плюс любые права на выполнение из источника, а каталоги создаются с режимом 0o777 (до umask).

CopyFS не перезаписывает существующие файлы. Если имя файла в fsys уже существует в месте назначения, CopyFS вернет ошибку, так что errors.Is(err, fs.ErrExist) будет true.

Символьные ссылки в fsys не поддерживаются. При копировании из символьной ссылки возвращается *PathError с Err, установленным в ErrInvalid.

Символьные ссылки в dir прослеживаются.

Новые файлы, добавленные в fsys (в том числе, если dir является подкаталогом fsys) во время работы CopyFS, не гарантированно будут скопированы.

Копирование останавливается при возникновении первой ошибки и возвращает ее.

func DirFS

func DirFS(dir string) fs.FS

DirFS возвращает файловую систему (fs.FS) для дерева файлов, корнем которого является каталог dir.

Обратите внимание, что DirFS(«/prefix») гарантирует только то, что вызовы Open, которые он делает в операционной системе, будут начинаться с «/prefix»: DirFS(«/prefix»).Open(„file“) равно os.Open(«/prefix/file»). Поэтому, если /prefix/file является символической ссылкой, указывающей за пределы дерева /prefix, то использование DirFS не останавливает доступ больше, чем использование os.Open. Кроме того, корень fs.FS, возвращаемый для относительного пути, DirFS(«prefix»), будет затронут последующими вызовами Chdir. Поэтому DirFS не является общей заменой механизма безопасности типа chroot, когда дерево каталогов содержит произвольное содержимое.

Используйте Root.FS, чтобы получить fs.FS, который предотвращает выход из дерева через символьные ссылки.

Каталог dir не должен быть «».

Результат реализует io/fs.StatFS, io/fs.ReadFileFS и io/fs.ReadDirFS.

func Environ

func Environ() []string

Environ возвращает копию строк, представляющих среду, в форме «ключ=значение».

func Executable

func Executable() (string, error)

Executable возвращает имя пути к исполняемому файлу, который запустил текущий процесс. Нет гарантии, что путь по-прежнему указывает на правильный исполняемый файл. Если для запуска процесса использовалась символьная ссылка, в зависимости от операционной системы результатом может быть символьная ссылка или путь, на который она указывала. Если требуется стабильный результат, может помочь path/filepath.EvalSymlinks.

Executable возвращает абсолютный путь, если не произошла ошибка.

Основной случай использования — поиск ресурсов, расположенных относительно исполняемого файла.

func Exit

func Exit(code int)

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

Для обеспечения переносимости код статуса должен находиться в диапазоне [0, 125].

func Expand

func Expand(s string, mapping func(string) string) string

Expand заменяет ${var} или $var в строке на основе функции сопоставления. Например, os.ExpandEnv(s) эквивалентно os.Expand(s, os.Getenv).

Пример
package main

import (
	"fmt"
	"os"
)

func main() {
	mapper := func(placeholderName string) string {
		switch placeholderName {
		case "DAY_PART":
			return "morning"
		case "NAME":
			return "Gopher"
		}

		return ""
	}

	fmt.Println(os.Expand("Good ${DAY_PART}, $NAME!", mapper))

}
Output:

Good morning, Gopher!

func ExpandEnv

func ExpandEnv(s string) string

ExpandEnv заменяет ${var} или $var в строке в соответствии со значениями текущих переменных окружения. Ссылки на неопределенные переменные заменяются пустой строкой.

Пример
package main

import (
	"fmt"
	"os"
)

func main() {
	os.Setenv("NAME", "gopher")
	os.Setenv("BURROW", "/usr/gopher")

	fmt.Println(os.ExpandEnv("$NAME lives in ${BURROW}."))

}
Output:

gopher lives in /usr/gopher.

func Getegid

func Getegid() int

Getegid возвращает числовой идентификатор эффективной группы вызывающего.

В Windows возвращает -1.

func Getenv

func Getenv(key string) string

Getenv извлекает значение переменной окружения, указанной ключом. Возвращает значение, которое будет пустым, если переменная отсутствует. Чтобы отличить пустое значение от не заданного значения, используйте LookupEnv.

Пример
package main

import (
	"fmt"
	"os"
)

func main() {
	os.Setenv("NAME", "gopher")
	os.Setenv("BURROW", "/usr/gopher")

	fmt.Printf("%s lives in %s.\n", os.Getenv("NAME"), os.Getenv("BURROW"))

}
Output:

gopher lives in /usr/gopher.

func Geteuid

func Geteuid() int

Geteuid возвращает числовой эффективный идентификатор пользователя вызывающего.

В Windows возвращает -1.

func Getgid

func Getgid() int

Getgid возвращает числовой идентификатор группы вызывающего.

В Windows возвращает -1.

func Getgroups

func Getgroups() ([]int, error)

Getgroups возвращает список числовых идентификаторов групп, к которым принадлежит вызывающий.

В Windows возвращает syscall.EWINDOWS. Возможную альтернативу см. в пакете os/user.

func Getpagesize

func Getpagesize() int

Getpagesize возвращает размер страницы памяти базовой системы.

func Getpid

func Getpid() int

Getpid возвращает идентификатор процесса вызывающего.

func Getppid

func Getppid() int

Getppid возвращает идентификатор процесса родителя вызывающего.

func Getuid

func Getuid() int

Getuid возвращает числовой идентификатор пользователя вызывающего.

В Windows возвращает -1.

func Getwd

func Getwd() (dir string, err error)

Getwd возвращает абсолютное имя пути, соответствующее текущему каталогу. Если к текущему каталогу можно перейти по нескольким путям (из-за символьных ссылок), Getwd может вернуть любой из них.

На платформах Unix, если переменная окружения PWD предоставляет абсолютное имя, и оно является именем текущего каталога, оно возвращается.

func Hostname

func Hostname() (name string, err error)

Hostname возвращает имя хоста, сообщаемое ядром.

func IsExist

func IsExist(err error) bool

IsExist возвращает булево значение, указывающее, известно ли, что файл или каталог уже существует. Оно удовлетворяется ErrExist, а также некоторыми ошибками системных вызовов.

Эта функция предшествует errors.Is. Она поддерживает только ошибки, возвращаемые пакетом os. В новом коде следует использовать errors.Is(err, fs.ErrExist).

func IsNotExist

func IsNotExist(err error) bool

IsNotExist возвращает булево значение, указывающее, известно ли, что аргумент сообщает о том, что файл или каталог не существует. Это условие выполняется для ErrNotExist, а также для некоторых ошибок системных вызовов.

Эта функция предшествует errors.Is. Она поддерживает только ошибки, возвращаемые пакетом os. В новом коде следует использовать errors.Is(err, fs.ErrNotExist).

func IsPathSeparator

func IsPathSeparator(c uint8) bool

IsPathSeparator сообщает, является ли c символом разделителя каталогов.

func IsPermission

func IsPermission(err error) bool

IsPermission возвращает булево значение, указывающее, известно ли, что аргумент сообщает об отказе в разрешении. Это условие выполняется ErrPermission, а также некоторыми ошибками системных вызовов.

Эта функция предшествует errors.Is. Она поддерживает только ошибки, возвращаемые пакетом os. В новом коде следует использовать errors.Is(err, fs.ErrPermission).

func IsTimeout

func IsTimeout(err error) bool

IsTimeout возвращает булево значение, указывающее, известно ли, что аргумент сообщает о возникновении таймаута.

Эта функция предшествует errors.Is, и понятие о том, указывает ли ошибка на тайм-аут, может быть неоднозначным. Например, ошибка Unix EWOULDBLOCK иногда указывает на тайм-аут, а иногда нет. В новом коде следует использовать errors.Is со значением, соответствующим вызову, возвращающему ошибку, например os.ErrDeadlineExceeded.

func Lchown

func Lchown(name string, uid, gid int) error

Lchown изменяет числовые значения uid и gid указанного файла. Если файл является символической ссылкой, то изменяются значения uid и gid самой ссылки. Если происходит ошибка, то она будет типа *PathError.

В Windows всегда возвращается ошибка syscall.EWINDOWS, обернутая в *PathError.

func Link(oldname, newname string) error

Link создает newname как жесткую ссылку на файл oldname. Если происходит ошибка, она будет типа *LinkError.

func LookupEnv

func LookupEnv(key string) (string, bool)

LookupEnv извлекает значение переменной окружения, указанной ключом. Если переменная присутствует в окружении, возвращается значение (которое может быть пустым) и булево значение true. В противном случае возвращаемое значение будет пустым, а булево значение будет false.

Пример
package main

import (
	"fmt"
	"os"
)

func main() {
	show := func(key string) {
		val, ok := os.LookupEnv(key)
		if !ok {
			fmt.Printf("%s not set\n", key)
		} else {
			fmt.Printf("%s=%s\n", key, val)
		}
	}

	os.Setenv("SOME_KEY", "value")
	os.Setenv("EMPTY_KEY", "")

	show("SOME_KEY")
	show("EMPTY_KEY")
	show("MISSING_KEY")

}
Output:

SOME_KEY=value
EMPTY_KEY=
MISSING_KEY not set

func Mkdir

func Mkdir(name string, perm FileMode) error

Mkdir создает новый каталог с указанным именем и битами разрешений (до umask). Если произошла ошибка, она будет типа *PathError.

Пример
package main

import (
	"log"
	"os"
)

func main() {
	err := os.Mkdir("testdir", 0750)
	if err != nil && !os.IsExist(err) {
		log.Fatal(err)
	}
	err = os.WriteFile("testdir/testfile.txt", []byte("Hello, Gophers!"), 0660)
	if err != nil {
		log.Fatal(err)
	}
}

func MkdirAll

func MkdirAll(path string, perm FileMode) error

MkdirAll создает каталог с именем path, а также все необходимые родительские каталоги, и возвращает nil, или же возвращает ошибку. Биты прав доступа perm (до umask) используются для всех каталогов, которые создает MkdirAll. Если path уже является каталогом, MkdirAll ничего не делает и возвращает nil.

Пример
package main

import (
	"log"
	"os"
)

func main() {
	err := os.MkdirAll("test/subdir", 0750)
	if err != nil {
		log.Fatal(err)
	}
	err = os.WriteFile("test/subdir/testfile.txt", []byte("Hello, Gophers!"), 0660)
	if err != nil {
		log.Fatal(err)
	}
}

func MkdirTemp

func MkdirTemp(dir, pattern string) (string, error)

MkdirTemp создает новый временный каталог в каталоге dir и возвращает путь к новому каталогу. Имя нового каталога генерируется путем добавления случайной строки в конец pattern. Если pattern содержит “*”, случайная строка заменяет последний “*”. Каталог создается с режимом 0o700 (до umask). Если dir — пустая строка, MkdirTemp использует каталог по умолчанию для временных файлов, возвращаемый TempDir. Несколько программ или goroutines, вызывающих MkdirTemp одновременно, не будут выбирать один и тот же каталог. Ответственность за удаление каталога, когда он больше не нужен, лежит на вызывающем.

Пример
package main

import (
	"log"
	"os"
	"path/filepath"
)

func main() {
	dir, err := os.MkdirTemp("", "example")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(dir) // clean up

	file := filepath.Join(dir, "tmpfile")
	if err := os.WriteFile(file, []byte("content"), 0666); err != nil {
		log.Fatal(err)
	}
}
Пример suffix
package main

import (
	"log"
	"os"
	"path/filepath"
)

func main() {
	logsDir, err := os.MkdirTemp("", "*-logs")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(logsDir) // clean up

	// Logs can be cleaned out earlier if needed by searching
	// for all directories whose suffix ends in *-logs.
	globPattern := filepath.Join(os.TempDir(), "*-logs")
	matches, err := filepath.Glob(globPattern)
	if err != nil {
		log.Fatalf("Failed to match %q: %v", globPattern, err)
	}

	for _, match := range matches {
		if err := os.RemoveAll(match); err != nil {
			log.Printf("Failed to remove %q: %v", match, err)
		}
	}
}

func NewSyscallError

func NewSyscallError(syscall string, err error) error

NewSyscallError возвращает в качестве ошибки новый SyscallError с указанным именем системного вызова и подробностями ошибки. Для удобства, если err равен nil, NewSyscallError возвращает nil.

func Pipe

func Pipe() (r *File, w *File, err error)

Pipe возвращает соединенную пару файлов; считывает из r байты, записанные в w. Он возвращает файлы и ошибку, если таковая имеется.

func ReadFile

func ReadFile(name string) ([]byte, error)

ReadFile считывает файл с указанным именем и возвращает его содержимое. Успешный вызов возвращает err == nil, а не err == EOF. Поскольку ReadFile считывает весь файл, он не рассматривает EOF из Read как ошибку, о которой следует сообщать.

Пример
package main

import (
	"log"
	"os"
)

func main() {
	data, err := os.ReadFile("testdata/hello")
	if err != nil {
		log.Fatal(err)
	}
	os.Stdout.Write(data)

}
Output:

Hello, Gophers!
func Readlink(name string) (string, error)

Readlink возвращает место назначения символической ссылки с указанным именем. Если произошла ошибка, она будет типа *PathError.

Если место назначения ссылки является относительным, Readlink возвращает относительный путь, не преобразуя его в абсолютный.

Пример
package main

import (
	"errors"
	"fmt"
	"log"
	"os"
	"path/filepath"
)

func main() {
	// First, we create a relative symlink to a file.
	d, err := os.MkdirTemp("", "")
	if err != nil {
		log.Fatal(err)
	}
	defer os.RemoveAll(d)
	targetPath := filepath.Join(d, "hello.txt")
	if err := os.WriteFile(targetPath, []byte("Hello, Gophers!"), 0644); err != nil {
		log.Fatal(err)
	}
	linkPath := filepath.Join(d, "hello.link")
	if err := os.Symlink("hello.txt", filepath.Join(d, "hello.link")); err != nil {
		if errors.Is(err, errors.ErrUnsupported) {
			// Allow the example to run on platforms that do not support symbolic links.
			fmt.Printf("%s links to %s\n", filepath.Base(linkPath), "hello.txt")
			return
		}
		log.Fatal(err)
	}

	// Readlink returns the relative path as passed to os.Symlink.
	dst, err := os.Readlink(linkPath)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s links to %s\n", filepath.Base(linkPath), dst)

	var dstAbs string
	if filepath.IsAbs(dst) {
		dstAbs = dst
	} else {
		// Symlink targets are relative to the directory containing the link.
		dstAbs = filepath.Join(filepath.Dir(linkPath), dst)
	}

	// Check that the target is correct by comparing it with os.Stat
	// on the original target path.
	dstInfo, err := os.Stat(dstAbs)
	if err != nil {
		log.Fatal(err)
	}
	targetInfo, err := os.Stat(targetPath)
	if err != nil {
		log.Fatal(err)
	}
	if !os.SameFile(dstInfo, targetInfo) {
		log.Fatalf("link destination (%s) is not the same file as %s", dstAbs, targetPath)
	}

}
Output:

hello.link links to hello.txt

func Remove

func Remove(name string) error

Remove удаляет указанный файл или (пустой) каталог. Если происходит ошибка, она будет типа *PathError.

func RemoveAll

func RemoveAll(path string) error

RemoveAll удаляет путь и все вложенные в него элементы. Он удаляет все, что может, но возвращает первую встреченную ошибку. Если путь не существует, RemoveAll возвращает nil (без ошибки). Если произошла ошибка, она будет типа *PathError.

func Rename

func Rename(oldpath, newpath string) error

Rename переименовывает (перемещает) oldpath в newpath. Если newpath уже существует и не является каталогом, Rename заменяет его. Если newpath уже существует и является каталогом, Rename возвращает ошибку. Ограничения, специфичные для ОС, могут применяться, когда oldpath и newpath находятся в разных каталогах. Даже в пределах одного каталога на платформах, отличных от Unix, Rename не является атомарной операцией. Если произошла ошибка, она будет типа *LinkError.

func SameFile

func SameFile(fi1, fi2 FileInfo) bool

SameFile сообщает, описывают ли fi1 и fi2 один и тот же файл. Например, в Unix это означает, что поля device и inode двух базовых структур идентичны; в других системах решение может основываться на именах путей. SameFile применяется только к результатам, возвращаемым Stat этого пакета. В других случаях она возвращает false.

func Setenv

func Setenv(key, value string) error

Setenv устанавливает значение переменной среды, указанной ключом. Возвращает ошибку, если таковая имеется.

func Symlink(oldname, newname string) error

Symlink создает newname как символическую ссылку на oldname. В Windows символическая ссылка на несуществующий oldname создает файловую символическую ссылку; если oldname позже будет создан как каталог, символическая ссылка не будет работать. Если произойдет ошибка, она будет типа *LinkError.

func TempDir

func TempDir() string

TempDir возвращает каталог по умолчанию, который будет использоваться для временных файлов.

В системах Unix она возвращает $TMPDIR, если он не пуст, в противном случае — /tmp. В Windows она использует GetTempPath, возвращая первое непустое значение из %TMP%, %TEMP%, %USERPROFILE% или каталога Windows. В Plan 9 она возвращает /tmp.

Существование каталога и наличие прав доступа к нему не гарантируются.

func Truncate

func Truncate(name string, size int64) error

Truncate изменяет размер указанного файла. Если файл является символической ссылкой, изменяется размер цели ссылки. Если происходит ошибка, она будет типа *PathError.

func Unsetenv

func Unsetenv(key string) error

Unsetenv снимает установку одной переменной среды.

Пример
package main

import (
	"os"
)

func main() {
	os.Setenv("TMPDIR", "/my/tmp")
	defer os.Unsetenv("TMPDIR")
}

func UserCacheDir

func UserCacheDir() (string, error)

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

В системах Unix она возвращает $XDG_CACHE_HOME, как указано в https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html, если он не пустой, в противном случае — $HOME/.cache. В Darwin она возвращает $HOME/Library/Caches. В Windows она возвращает %LocalAppData%. В Plan 9 она возвращает $home/lib/cache.

Если местоположение не может быть определено (например, $HOME не определено) или путь в $XDG_CACHE_HOME является относительным, то будет возвращена ошибка.

Пример
import (
	"log"
	"os"
	"path/filepath"
	"sync"
)

func main() {
	dir, dirErr := os.UserCacheDir()
	if dirErr == nil {
		dir = filepath.Join(dir, "ExampleUserCacheDir")
	}

	getCache := func(name string) ([]byte, error) {
		if dirErr != nil {
			return nil, &os.PathError{Op: "getCache", Path: name, Err: os.ErrNotExist}
		}
		return os.ReadFile(filepath.Join(dir, name))
	}

	var mkdirOnce sync.Once
	putCache := func(name string, b []byte) error {
		if dirErr != nil {
			return &os.PathError{Op: "putCache", Path: name, Err: dirErr}
		}
		mkdirOnce.Do(func() {
			if err := os.MkdirAll(dir, 0700); err != nil {
				log.Printf("can't create user cache dir: %v", err)
			}
		})
		return os.WriteFile(filepath.Join(dir, name), b, 0600)
	}

	// Read and store cached data.
	// …
	_ = getCache
	_ = putCache

}

func UserConfigDir

func UserConfigDir() (string, error)

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

В системах Unix она возвращает $XDG_CONFIG_HOME, как указано в https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html, если он не пустой, в противном случае — $HOME/.config. В Darwin она возвращает $HOME/Library/Application Support. В Windows она возвращает %AppData%. В Plan 9 она возвращает $home/lib.

Если местоположение не может быть определено (например, $HOME не определено) или путь в $XDG_CONFIG_HOME является относительным, то будет возвращена ошибка.

Пример
package main

import (
	"bytes"
	"log"
	"os"
	"path/filepath"
)

func main() {
	dir, dirErr := os.UserConfigDir()

	var (
		configPath string
		origConfig []byte
	)
	if dirErr == nil {
		configPath = filepath.Join(dir, "ExampleUserConfigDir", "example.conf")
		var err error
		origConfig, err = os.ReadFile(configPath)
		if err != nil && !os.IsNotExist(err) {
			// The user has a config file but we couldn't read it.
			// Report the error instead of ignoring their configuration.
			log.Fatal(err)
		}
	}

	// Use and perhaps make changes to the config.
	config := bytes.Clone(origConfig)
	// …

	// Save changes.
	if !bytes.Equal(config, origConfig) {
		if configPath == "" {
			log.Printf("not saving config changes: %v", dirErr)
		} else {
			err := os.MkdirAll(filepath.Dir(configPath), 0700)
			if err == nil {
				err = os.WriteFile(configPath, config, 0600)
			}
			if err != nil {
				log.Printf("error saving config changes: %v", err)
			}
		}
	}

}

func UserHomeDir

func UserHomeDir() (string, error)

UserHomeDir возвращает домашний каталог текущего пользователя.

В Unix, включая macOS, возвращает переменную среды $HOME. В Windows возвращает %USERPROFILE%. В Plan 9 возвращает переменную среды $home.

Если ожидаемая переменная не задана в среде, UserHomeDir возвращает либо значение по умолчанию, специфичное для платформы, либо ошибку, отличную от nil.

func WriteFile

func WriteFile(name string, data []byte, perm FileMode) error

WriteFile записывает данные в файл с указанным именем, создавая его при необходимости. Если файл не существует, WriteFile создает его с правами доступа perm (до umask); в противном случае WriteFile обрезает его перед записью, не изменяя права доступа. Поскольку WriteFile требует нескольких системных вызовов для завершения, сбой в середине операции может оставить файл в частично записанном состоянии.

Пример
package main

import (
	"log"
	"os"
)

func main() {
	err := os.WriteFile("testdata/hello", []byte("Hello, Gophers!"), 0666)
	if err != nil {
		log.Fatal(err)
	}
}

2 - Описание типов пакета os языка программирования Go

Основные типы пакета os языка программирования GO

type DirEntry

type DirEntry = fs.DirEntry

DirEntry — это запись, прочитанная из каталога (с помощью функции ReadDir или метода File.ReadDir).

func ReadDir

func ReadDir(name string) ([]DirEntry, error)

ReadDir считывает указанный каталог и возвращает все его записи, отсортированные по имени файла. Если при чтении каталога происходит ошибка, ReadDir возвращает записи, которые удалось прочитать до ошибки, вместе с ошибкой.

Пример
package main

import (
	"fmt"
	"log"
	"os"
)

func main() {
	files, err := os.ReadDir(".")
	if err != nil {
		log.Fatal(err)
	}

	for _, file := range files {
		fmt.Println(file.Name())
	}
}

type File

type File struct {
    // содержит отфильтрованные или неэкспортируемые поля
}

File представляет открытый файловый дескриптор.

Методы File безопасны для одновременного использования.

func Create

func Create(name string) (*File, error)

Create создает или обрезает файл с указанным именем. Если файл уже существует, он обрезается. Если файл не существует, он создается с режимом 0o666 (до umask). В случае успеха методы возвращенного File могут использоваться для ввода-вывода; связанный файловый дескриптор имеет режим O_RDWR. Каталог, содержащий файл, должен уже существовать. Если произошла ошибка, она будет типа *PathError.

func CreateTemp

func CreateTemp(dir, pattern string) (*File, error)

CreateTemp создает новый временный файл в каталоге dir, открывает файл для чтения и записи и возвращает полученный файл. Имя файла генерируется путем добавления случайной строки в конец pattern. Если pattern содержит "*", случайная строка заменяет последний "*". Файл создается с режимом 0o600 (до umask). Если dir — пустая строка, CreateTemp использует каталог по умолчанию для временных файлов, возвращаемый TempDir. Несколько программ или goroutines, вызывающих CreateTemp одновременно, не будут выбирать один и тот же файл. Вызывающий может использовать метод Name файла, чтобы найти путь к файлу. Вызывающий несет ответственность за удаление файла, когда он больше не нужен.

Пример
package main

import (
	"log"
	"os"
)

func main() {
	f, err := os.CreateTemp("", "example")
	if err != nil {
		log.Fatal(err)
	}
	defer os.Remove(f.Name()) // clean up

	if _, err := f.Write([]byte("content")); err != nil {
		log.Fatal(err)
	}
	if err := f.Close(); err != nil {
		log.Fatal(err)
	}
}
Пример suffix
package main

import (
	"log"
	"os"
)

func main() {
	f, err := os.CreateTemp("", "example.*.txt")
	if err != nil {
		log.Fatal(err)
	}
	defer os.Remove(f.Name()) // clean up

	if _, err := f.Write([]byte("content")); err != nil {
		f.Close()
		log.Fatal(err)
	}
	if err := f.Close(); err != nil {
		log.Fatal(err)
	}
}

func NewFile

func NewFile(fd uintptr, name string) *File

NewFile возвращает новый File с заданным файловым дескриптором и именем. Возвращаемое значение будет nil, если fd не является действительным файловым дескриптором. В системах Unix, если файловый дескриптор находится в неблокирующем режиме, NewFile попытается вернуть опрашиваемый File (такой, для которого работают методы SetDeadline).

После передачи в NewFile fd может стать недействительным при тех же условиях, что описаны в комментариях к методу Fd, и применяются те же ограничения.

func Open

func Open(name string) (*File, error)

Open открывает указанный файл для чтения. В случае успеха методы возвращенного файла могут быть использованы для чтения; связанный файловый дескриптор имеет режим O_RDONLY. Если произошла ошибка, она будет типа *PathError.

func OpenFile

func OpenFile(name string, flag int, perm FileMode) (*File, error)

OpenFile — это обобщенный вызов open; большинство пользователей вместо него будут использовать Open или Create. Он открывает файл с указанным флагом (O_RDONLY и т. д.). Если файл не существует и передан флаг O_CREATE, он создается с режимом perm (до umask); содержащий его каталог должен существовать. В случае успеха методы возвращенного File можно использовать для ввода-вывода. Если произошла ошибка, она будет типа *PathError.

Пример
package main

import (
	"log"
	"os"
)

func main() {
	f, err := os.OpenFile("notes.txt", os.O_RDWR|os.O_CREATE, 0644)
	if err != nil {
		log.Fatal(err)
	}
	if err := f.Close(); err != nil {
		log.Fatal(err)
	}
}
Пример добавление
package main

import (
	"log"
	"os"
)

func main() {
	// If the file doesn't exist, create it, or append to the file
	f, err := os.OpenFile("access.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
	if err != nil {
		log.Fatal(err)
	}
	if _, err := f.Write([]byte("appended some data\n")); err != nil {
		f.Close() // ignore error; Write error takes precedence
		log.Fatal(err)
	}
	if err := f.Close(); err != nil {
		log.Fatal(err)
	}
}

func OpenInRoot

func OpenInRoot(dir, name string) (*File, error)

OpenInRoot открывает файл name в каталоге dir. Это эквивалентно OpenRoot(dir) с последующим открытием файла в корневом каталоге.

OpenInRoot возвращает ошибку, если какой-либо компонент имени name ссылается на местоположение за пределами dir.

См. Root для получения подробной информации и ограничений.

func (*File) Chdir

func (f *File) Chdir() error

Chdir изменяет текущий рабочий каталог на файл, который должен быть каталогом. Если произошла ошибка, она будет типа *PathError.

func (*File) Chmod

func (f *File) Chmod(mode FileMode) error

Chmod изменяет режим файла на mode. Если произошла ошибка, она будет типа *PathError.

func (*File) Chown

func (f *File) Chown(uid, gid int) error

Chown изменяет числовые значения uid и gid указанного файла. Если произошла ошибка, она будет типа *PathError.

В Windows всегда возвращается ошибка syscall.EWINDOWS, обернутая в *PathError.

func (*File) Close

func (f *File) Close() error

Close закрывает файл, делая его недоступным для ввода-вывода. Для файлов, поддерживающих File.SetDeadline, все ожидающие операции ввода-вывода будут отменены и немедленно возвращены с ошибкой ErrClosed. Close вернет ошибку, если он уже был вызван.

func (*File) Fd

func (f *File) Fd() uintptr

Fd возвращает целое число Unix-дескриптора файла, ссылающегося на открытый файл. Если f закрыт, дескриптор файла становится недействительным. Если f подвергается сборке мусора, финализатор может закрыть дескриптор файла, сделав его недействительным; см. runtime.SetFinalizer для получения дополнительной информации о том, когда может быть запущен финализатор. В системах Unix это приведет к прекращению работы методов File.SetDeadline. Поскольку файловые дескрипторы могут быть повторно использованы, возвращенный файловый дескриптор может быть закрыт только с помощью метода File.Close f или его финализатором во время сборки мусора. В противном случае во время сборки мусора финализатор может закрыть не связанный файловый дескриптор с тем же (повторно используемым) номером.

В качестве альтернативы см. метод f.SyscallConn.

func (*File) Name

func (f *File) Name() string

Name возвращает имя файла, представленное в Open.

Безопасно вызывать Name после [Close].

func (*File) Read

func (f *File) Read(b []byte) (n int, err error)

Read считывает до len(b) байтов из File и сохраняет их в b. Он возвращает количество прочитанных байтов и любую возникшую ошибку. В конце файла Read возвращает 0, io.EOF.

func (*File) ReadAt

func (f *File) ReadAt(b []byte, off int64) (n int, err error)

ReadAt считывает len(b) байт из файла, начиная с байтового смещения off. Она возвращает количество прочитанных байтов и ошибку, если таковая имеется. ReadAt всегда возвращает ошибку, отличную от nil, когда n < len(b). В конце файла эта ошибка равна io.EOF.

func (*File) ReadDir

func (f *File) ReadDir(n int) ([]DirEntry, error)

ReadDir считывает содержимое каталога, связанного с файлом f, и возвращает массив значений DirEntry в порядке каталога. Последующие вызовы для того же файла будут возвращать последующие записи DirEntry в каталоге.

Если n > 0, ReadDir возвращает не более n записей DirEntry. В этом случае, если ReadDir возвращает пустой срез, он вернет ошибку с объяснением причины. В конце каталога ошибкой является io.EOF.

Если n <= 0, ReadDir возвращает все записи DirEntry, оставшиеся в каталоге. При успешном выполнении он возвращает ошибку nil (не io.EOF).

func (*File) ReadFrom

func (f *File) ReadFrom(r io.Reader) (n int64, err error)

ReadFrom реализует io.ReaderFrom.

func (*File) Readdir

func (f *File) Readdir(n int) ([]FileInfo, error)

Readdir считывает содержимое каталога, связанного с файлом, и возвращает массив из n значений FileInfo, как это было бы возвращено Lstat, в порядке каталога. Последующие вызовы для того же файла будут возвращать дополнительные FileInfos.

Если n > 0, Readdir возвращает не более n структур FileInfo. В этом случае, если Readdir возвращает пустой срез, он вернет не нулевую ошибку с объяснением причины. В конце каталога ошибкой является io.EOF.

Если n <= 0, Readdir возвращает все FileInfo из каталога в одном срезе. В этом случае, если Readdir выполняется успешно (считывает до конца каталога), он возвращает срез и ошибку nil. Если он встречает ошибку до конца каталога, Readdir возвращает FileInfo, прочитанные до этого момента, и ошибку, отличную от nil.

Большинству клиентов лучше подходит более эффективный метод ReadDir.

func (*File) Readdirnames

func (f *File) Readdirnames(n int) (names []string, err error)

Readdirnames считывает содержимое каталога, связанного с файлом, и возвращает срез из n имен файлов в каталоге в порядке их расположения в каталоге. Последующие вызовы для того же файла будут возвращать дальнейшие имена.

Если n > 0, Readdirnames возвращает не более n имен. В этом случае, если Readdirnames возвращает пустой срез, он возвращает не нулевую ошибку с объяснением причины. В конце каталога ошибкой является io.EOF.

Если n <= 0, Readdirnames возвращает все имена из каталога в одном фрагменте. В этом случае, если Readdirnames выполняется успешно (считывает до конца каталога), он возвращает фрагмент и ошибку nil. Если перед концом каталога возникает ошибка, Readdirnames возвращает имена, прочитанные до этого момента, и ошибку, отличную от nil.

func (*File) Seek

func (f *File) Seek(offset int64, whence int) (ret int64, err error)

Seek устанавливает смещение для следующего чтения или записи в файл, интерпретируемое в соответствии с whence: 0 означает относительно начала файла, 1 означает относительно текущего смещения, а 2 означает относительно конца. Возвращает новое смещение и ошибку, если она есть. Поведение Seek для файла, открытого с O_APPEND, не определено.

func (*File) SetDeadline

func (f *File) SetDeadline(t time.Time) error

SetDeadline устанавливает сроки чтения и записи для файла. Это эквивалентно вызову SetReadDeadline и SetWriteDeadline.

Только некоторые типы файлов поддерживают установку срока. Вызов SetDeadline для файлов, которые не поддерживают сроки, вернет ErrNoDeadline. В большинстве систем обычные файлы не поддерживают сроки, но каналы поддерживают.

Срок — это абсолютное время, по истечении которого операции ввода-вывода завершаются с ошибкой, а не блокируются. Срок применяется ко всем будущим и ожидающим операциям ввода-вывода, а не только к следующему вызову Read или Write. После превышения срока соединение можно обновить, установив срок в будущем.

Если срок превышен, вызов Read или Write или других методов ввода-вывода вернет ошибку, которая оборачивает ErrDeadlineExceeded. Это можно проверить с помощью errors.Is(err, os.ErrDeadlineExceeded). Эта ошибка реализует метод Timeout, и вызов метода Timeout вернет true, но есть и другие возможные ошибки, для которых Timeout вернет true, даже если срок не был превышен.

Таймаут простоя можно реализовать путем многократного продления срока после успешных вызовов Read или Write.

Нулевое значение t означает, что операции ввода-вывода не будут прерываться по истечении таймаута.

func (*File) SetReadDeadline

func (f *File) SetReadDeadline(t time.Time) error

SetReadDeadline устанавливает срок для будущих вызовов Read и любых заблокированных в данный момент вызовов Read. Нулевое значение t означает, что Read не будет прерываться по истечении времени ожидания. Не все файлы поддерживают установку сроков; см. SetDeadline.

func (*File) SetWriteDeadline

func (f *File) SetWriteDeadline(t time.Time) error

SetWriteDeadline устанавливает срок для любых будущих вызовов Write и любых заблокированных в данный момент вызовов Write. Даже если Write превышает время ожидания, он может вернуть n > 0, указывая, что часть данных была успешно записана. Нулевое значение t означает, что Write не превысит время ожидания. Не все файлы поддерживают установку сроков; см. SetDeadline.

func (*File) Stat

func (f *File) Stat() (FileInfo, error)

Stat возвращает структуру FileInfo, описывающую файл. Если произошла ошибка, она будет иметь тип *PathError.

func (*File) Sync

func (f *File) Sync() error

Sync фиксирует текущее содержимое файла в стабильном хранилище. Обычно это означает сброс в память файловой системы копии недавно записанных данных на диск.

func (*File) SyscallConn

func (f *File) SyscallConn() (syscall.RawConn, error)

SyscallConn возвращает необработанный файл. Это реализует интерфейс syscall.Conn.

func (*File) Truncate

func (f *File) Truncate(size int64) error

Truncate изменяет размер файла. Он не изменяет смещение ввода-вывода. Если происходит ошибка, она будет типа *PathError.

func (*File) Write

func (f *File) Write(b []byte) (n int, err error)

Write записывает len(b) байт из b в File. Он возвращает количество записанных байт и ошибку, если она есть. Write возвращает ошибку, отличную от nil, когда n != len(b).

func (*File) WriteAt

func (f *File) WriteAt(b []byte, off int64) (n int, err error)

WriteAt записывает len(b) байт в файл, начиная с байтового смещения off. Он возвращает количество записанных байтов и ошибку, если она есть. WriteAt возвращает ошибку, отличную от nil, когда n != len(b).

Если файл был открыт с флагом O_APPEND, WriteAt возвращает ошибку.

func (*File) WriteString

func (f *File) WriteString(s string) (n int, err error)

WriteString похож на Write, но записывает содержимое строки s, а не фрагмент байтов.

func (*File) WriteTo

func (f *File) WriteTo(w io.Writer) (n int64, err error)

WriteTo реализует io.WriterTo.

type FileInfo

type FileInfo = fs.FileInfo

FileInfo описывает файл и возвращается Stat и Lstat.

func Lstat

func Lstat(name string) (FileInfo, error)

Lstat возвращает FileInfo, описывающий файл с указанным именем. Если файл является символической ссылкой, возвращаемый FileInfo описывает символическую ссылку. Lstat не пытается следовать по ссылке. Если происходит ошибка, она будет типа *PathError.

В Windows, если файл является точкой повторного анализа, которая является заменителем другого именованного объекта (например, символической ссылки или смонтированной папки), возвращаемый FileInfo описывает точку повторного анализа и не пытается ее разрешить.

func Stat

func Stat(name string) (FileInfo, error)

Stat возвращает FileInfo, описывающий именованный файл. Если произошла ошибка, она будет типа *PathError.

type FileMode

type FileMode = fs.FileMode

FileMode представляет режим файла и биты разрешений. Биты имеют одинаковое определение во всех системах, поэтому информация о файлах может быть перенесена из одной системы в другую. Не все биты применимы ко всем системам. Единственный обязательный бит — ModeDir для каталогов.

Пример ¶

type LinkError

type LinkError struct {
    Op  string
    Old string
    New string
    Err error
}

LinkError записывает ошибку, возникшую во время системного вызова link, symlink или rename, а также пути, которые ее вызвали.

func (*LinkError) Error

func (e *LinkError) Error() string

func (*LinkError) Unwrap

func (e *LinkError) Unwrap() error

type PathError

type PathError = fs.PathError

PathError регистрирует ошибку, а также операцию и путь к файлу, которые ее вызвали.

type ProcAttr

type ProcAttr struct {
    // Если Dir не пустой, дочерний процесс переходит в этот каталог перед
    // созданием процесса.
    Dir string
	// Если Env не равно nil, оно возвращает переменные окружения для
    // нового процесса в форме, возвращаемой Environ.
    // Если оно равно nil, будет использован результат Environ.
    Env []string
    // Files указывает открытые файлы, унаследованные новым процессом.
    // Первые три записи соответствуют стандартному вводу, стандартному выводу и
    // стандартной ошибке. Реализация может поддерживать дополнительные записи,
	// в зависимости от базовой операционной системы. Запись nil соответствует
    // закрытию этого файла при запуске процесса.
    // В системах Unix StartProcess изменит эти значения File
    // в режим блокировки, что означает, что SetDeadline перестанет работать,
    // а вызов Close не прервет Read или Write.
    Files []*File

    // Атрибуты создания процесса, специфичные для операционной системы.
	// Обратите внимание, что установка этого поля означает, что ваша программа
    // может не работать должным образом или даже не компилироваться в некоторых
    // операционных системах.
    Sys *syscall.SysProcAttr
}

ProcAttr содержит атрибуты, которые будут применены к новому процессу, запущенному StartProcess.

type Process

type Process struct {
    Pid int
    // содержит отфильтрованные или неэкспортируемые поля
}

Process хранит информацию о процессе, созданном StartProcess.

func FindProcess

func FindProcess(pid int) (*Process, error)

FindProcess ищет запущенный процесс по его pid.

Возвращаемый им Process можно использовать для получения информации о процессе базовой операционной системы.

В системах Unix FindProcess всегда выполняется успешно и возвращает Process для заданного pid, независимо от того, существует ли процесс. Чтобы проверить, действительно ли процесс существует, посмотрите, сообщает ли p.Signal(syscall.Signal(0)) об ошибке.

func StartProcess

func StartProcess(name string, argv []string, attr *ProcAttr) (*Process, error)

StartProcess запускает новый процесс с программой, аргументами и атрибутами, указанными в name, argv и attr. Срез argv станет os.Args в новом процессе, поэтому он обычно начинается с имени программы.

Если вызывающая goroutine заблокировала поток операционной системы с помощью runtime.LockOSThread и изменила любое наследуемое состояние потока на уровне ОС (например, пространства имен Linux или Plan 9), новый процесс унаследует состояние потока вызывающего.

StartProcess является низкоуровневым интерфейсом. Пакет os/exec предоставляет интерфейсы более высокого уровня.

Если произошла ошибка, она будет иметь тип *PathError.

func (*Process) Kill

func (p *Process) Kill() error

Kill вызывает немедленный выход Process. Kill не ждет, пока Process действительно завершится. Это убивает только сам Process, а не другие процессы, которые он мог запустить.

func (*Process) Release

func (p *Process) Release() error

Release освобождает все ресурсы, связанные с процессом p, делая его непригодным для использования в будущем. Release нужно вызывать только в том случае, если Process.Wait не вызывается.

func (*Process) Signal

func (p *Process) Signal(sig Signal) error

Signal посылает сигнал процессу. Отправка Interrupt в Windows не реализована.

func (*Process) Wait

func (p *Process) Wait() (*ProcessState, error)

Wait ожидает завершения процесса, а затем возвращает ProcessState, описывающий его состояние, и ошибку, если она есть. Wait освобождает все ресурсы, связанные с процессом. В большинстве операционных систем процесс должен быть дочерним по отношению к текущему процессу, иначе будет возвращена ошибка.

type ProcessState

type ProcessState struct {
    // содержит отфильтрованные или неэкспортируемые поля
}

ProcessState хранит информацию о процессе, как сообщается Wait.

func (*ProcessState) ExitCode

func (p *ProcessState) ExitCode() int

ExitCode возвращает код завершения завершившегося процесса или -1, если процесс не завершился или был прерван сигналом.

func (*ProcessState) Exited

func (p *ProcessState) Exited() bool

Exited сообщает, завершилась ли программа. В системах Unix это возвращает true, если программа завершилась из-за вызова exit, но false, если программа была прервана сигналом.

func (*ProcessState) Pid

func (p *ProcessState) Pid() int

Pid возвращает идентификатор завершившегося процесса.

func (*ProcessState) String

func (p *ProcessState) String() string

func (*ProcessState) Success

func (p *ProcessState) Success() bool

Success сообщает, завершилась ли программа успешно, например, со статусом завершения 0 в Unix.

func (*ProcessState) Sys

func (p *ProcessState) Sys() any

Sys возвращает системную информацию о завершении процесса. Преобразуйте ее в соответствующий базовый тип, например syscall.WaitStatus в Unix, чтобы получить доступ к ее содержимому.

func (*ProcessState) SysUsage

func (p *ProcessState) SysUsage() any

SysUsage возвращает системную информацию об использовании ресурсов завершенного процесса. Преобразуйте ее в соответствующий базовый тип, например *syscall.Rusage в Unix, чтобы получить доступ к ее содержимому. (В Unix *syscall.Rusage соответствует struct rusage, как определено в справочной странице getrusage(2).)

func (*ProcessState) SystemTime

func (p *ProcessState) SystemTime() time.Duration

SystemTime возвращает системное время ЦП завершенного процесса и его дочерних процессов.

func (*ProcessState) UserTime

func (p *ProcessState) UserTime() time.Duration

UserTime возвращает пользовательское время ЦП завершенного процесса и его дочерних процессов.

type Root


type Root struct {
    // содержит отфильтрованные или неэкспортируемые поля
}

Root может использоваться только для доступа к файлам в пределах одного дерева каталогов.

Методы Root могут обращаться только к файлам и каталогам, расположенным ниже корневого каталога. Если какой-либо компонент имени файла, переданного методу Root, ссылается на местоположение за пределами корня, метод возвращает ошибку. Имена файлов могут ссылаться на сам каталог (.).

Методы Root будут следовать символьным ссылкам, но символьные ссылки не могут ссылаться на местоположение за пределами корня. Символьные ссылки не должны быть абсолютными.

Методы Root не запрещают переход через границы файловой системы, монтирование Linux, специальные файлы /proc или доступ к файлам устройств Unix.

Методы Root можно безопасно использовать одновременно из нескольких goroutines.

На большинстве платформ создание Root открывает файловый дескриптор или дескриптор, ссылающийся на каталог. Если каталог перемещен, методы Root ссылаются на исходный каталог в его новом местоположении.

Поведение Root отличается на некоторых платформах:

  • Когда GOOS=windows, имена файлов не могут ссылаться на зарезервированные Windows имена устройств, такие как NUL и COM1.
  • Когда GOOS=js, Root уязвим для атак TOCTOU (time-of-check-time-of-use) при проверке символьных ссылок и не может гарантировать, что операции не выйдут за пределы корня.
  • Когда GOOS=plan9 или GOOS=js, Root не отслеживает каталоги при переименовании. На этих платформах Root ссылается на имя каталога, а не на файловый дескриптор.

func OpenRoot

func OpenRoot(name string) (*Root, error)

OpenRoot открывает указанный каталог. Если произошла ошибка, она будет типа *PathError.

func (*Root) Close

func (r *Root) Close() error

Close закрывает Root. После вызова Close методы Root возвращают ошибки.

func (*Root) Create

func (r *Root) Create(name string) (*File, error)

Create создает или обрезает указанный файл в корне. Подробнее см. Create.

func (*Root) FS

func (r *Root) FS() fs.FS

FS возвращает файловую систему (fs.FS) для дерева файлов в корне.

Результат реализует io/fs.StatFS, io/fs.ReadFileFS и io/fs.ReadDirFS.

func (*Root) Lstat

func (r *Root) Lstat(name string) (FileInfo, error)

Lstat возвращает FileInfo, описывающий указанный файл в корневом каталоге. Если файл является символической ссылкой, возвращаемый FileInfo описывает символическую ссылку. Подробнее см. Lstat.

func (*Root) Mkdir

func (r *Root) Mkdir(name string, perm FileMode) error

Mkdir создает новый каталог в корне с указанным именем и битами разрешений (до umask). Подробнее см. Mkdir.

Если perm содержит биты, отличные от девяти младших битов (0o777), OpenFile возвращает ошибку.

func (*Root) Name

func (r *Root) Name() string

Name возвращает имя каталога, представленного OpenRoot.

Безопасно вызывать Name после [Close].

func (*Root) Open

func (r *Root) Open(name string) (*File, error)

Open открывает указанный файл в корне для чтения. Подробнее см. Open.

func (*Root) OpenFile

func (r *Root) OpenFile(name string, flag int, perm FileMode) (*File, error)

OpenFile открывает указанный файл в корне. Подробнее см. OpenFile.

Если perm содержит биты, отличные от девяти младших битов (0o777), OpenFile возвращает ошибку.

func (*Root) OpenRoot

func (r *Root) OpenRoot(name string) (*Root, error)

OpenRoot открывает указанный каталог в корневом каталоге. Если произошла ошибка, она будет типа *PathError.

func (*Root) Remove

func (r *Root) Remove(name string) error

Remove удаляет указанный файл или (пустой) каталог в корневом каталоге. Подробнее см. в разделе Remove.

func (*Root) Stat

func (r *Root) Stat(name string) (FileInfo, error)

Stat возвращает FileInfo, описывающий файл с указанным именем в корне. Подробнее см. Stat.

type Signal

type Signal interface {
    String() string
    Signal() // для отличия от других Stringers
}

Signal представляет сигнал операционной системы. Обычная базовая реализация зависит от операционной системы: в Unix это syscall.Signal.

var (
    Interrupt Signal = syscall.SIGINT
	Kill      Signal = syscall.SIGKILL)

Единственные значения сигналов, которые гарантированно присутствуют в пакете os на всех системах, — это os.Interrupt (отправить процессу прерывание) и os.Kill (принудительно завершить процесс). В Windows отправка os.Interrupt процессу с помощью os.Process.Signal не реализована; вместо отправки сигнала будет возвращена ошибка.

type SyscallError

type SyscallError struct {
    Syscall string
    Err     error
}

SyscallError регистрирует ошибку от конкретного системного вызова.

func (*SyscallError) Error

func (e *SyscallError) Error() string

func (*SyscallError) Timeout

func (e *SyscallError) Timeout() bool

Timeout сообщает, является ли эта ошибка тайм-аутом.

func (*SyscallError) Unwrap

func (e *SyscallError) Unwrap() error

3 - Описание функций и типов пакета os/exec языка программирования Go

Пакет exec запускает внешние команды. Он оборачивает os.StartProcess, чтобы упростить перенаправление stdin и stdout, подключение ввода-вывода с помощью труб и другие настройки.

В отличие от вызова библиотеки «system» из C и других языков, пакет os/exec намеренно не вызывает системную оболочку и не расширяет никакие шаблоны glob, а также не обрабатывает другие расширения, конвейеры или перенаправления, которые обычно выполняются оболочками. Пакет ведет себя больше как семейство функций «exec» в C. Чтобы расширить шаблоны glob, либо вызовите оболочку напрямую, позаботившись об экранировании опасных входных данных, либо используйте функцию Glob из пакета path/filepath. Для расширения переменных окружения используйте ExpandEnv из пакета os.

Обратите внимание, что примеры в этом пакете предполагают использование системы Unix. Они могут не работать в Windows и не работают в Go Playground, используемом golang.org и godoc.org.

Исполняемые файлы в текущем каталоге

Функции Command и LookPath ищут программу в каталогах, перечисленных в текущем пути, следуя соглашениям операционной системы хоста. На протяжении десятилетий операционные системы включали текущий каталог в этот поиск, иногда неявно, а иногда явно настраивая его таким образом по умолчанию. Современная практика такова, что включение текущего каталога обычно является неожиданным и часто приводит к проблемам безопасности.

Чтобы избежать этих проблем безопасности, начиная с Go 1.19, этот пакет не будет разрешать программу, используя явную или неявную запись пути относительно текущего каталога. То есть, если вы запустите LookPath(“go”), он не вернет ./go в Unix и .\go.exe в Windows, независимо от того, как настроен путь. Вместо этого, если обычные алгоритмы пути приведут к такому ответу, эти функции возвращают ошибку err, удовлетворяющую errors.Is(err, ErrDot).

Рассмотрим, например, эти два фрагмента программы:

path, err := exec.LookPath("prog")
if err != nil {
	log.Fatal(err)
}
use(path)
cmd := exec.Command("prog")
if err := cmd.Run(); err != nil {
	log.Fatal(err)
}

Они не найдут и не запустят ./prog или .\prog.exe, независимо от того, как настроен текущий путь.

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

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

path, err := exec.LookPath("prog")
if errors.Is(err, exec.ErrDot) {
	err = nil
}
if err != nil {
	log.Fatal(err)
}
use(path)
cmd := exec.Command("prog")
if errors.Is(cmd.Err, exec.ErrDot) {
	cmd.Err = nil
}
if err := cmd.Run(); err != nil {
	log.Fatal(err)
}

Установка переменной окружения GODEBUG=execerrdot=0 полностью отключает генерацию ErrDot, временно восстанавливая поведение, существовавшее до Go 1.19, для программ, которые не могут применить более целевые исправления. В будущих версиях Go поддержка этой переменной может быть удалена.

Прежде чем добавлять такие переопределения, убедитесь, что вы понимаете последствия этого для безопасности. Дополнительные сведения см. на сайте https://go.dev/blog/path-security.

Переменные

var ErrDot = errors.New("cannot run executable found relative to current directory")

ErrDot указывает, что поиск пути привел к появлению исполняемого файла в текущем каталоге из-за ‘.’ в пути, либо неявно, либо явно. Подробности см. в документации к пакету.

Обратите внимание, что функции этого пакета не возвращают ErrDot напрямую. Для проверки того, связана ли возвращаемая ошибка err с этим условием, в коде следует использовать errors.Is(err, ErrDot), а не err == ErrDot.

var ErrNotFound = errors.New("исполняемый файл не найден в $PATH")

ErrNotFound - это ошибка, возникающая, если при поиске по пути не удалось найти исполняемый файл.

var ErrWaitDelay = errors.New("exec: WaitDelay expired before I/O complete")

ErrWaitDelay возвращается Cmd.Wait, если процесс завершается с успешным кодом состояния, но его выходные трубы не закрыты до истечения WaitDelay команды.

Функции

func LookPath

func LookPath(file string) (string, error)

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

В старых версиях Go LookPath мог возвращать путь относительно текущего каталога. Начиная с Go 1.19, LookPath будет возвращать этот путь вместе с ошибкой, удовлетворяющей errors.Is(err, ErrDot). Более подробную информацию см. в документации к пакету.

Пример
package main

import (
	"fmt"
	"log"
	"os/exec"
)

func main() {
	path, err := exec.LookPath("fortune")
	if err != nil {
		log.Fatal("installing fortune is in your future")
	}
	fmt.Printf("fortune is available at %s\n", path)
}

Типы

type Cmd

type Cmd struct {
    // Path — путь к выполняемой команде.
    //
    // Это единственное поле, которое должно иметь значение, отличное от нуля.
    // Если Path является относительным, оно оценивается относительно
    // Dir.
    Path string

    // Args содержит аргументы командной строки, включая команду как Args[0].
	// Если поле Args пустое или равно nil, Run использует {Path}.
    //
    // В типичном случае Path и Args задаются вызовом Command.
    Args []string

    // Env задает среду процесса.
    // Каждая запись имеет вид «ключ=значение».
    // Если Env равно nil, новый процесс использует среду текущего процесса.
    //
	// Если Env содержит дубликаты ключей среды, используется только последнее
    // значение в срезе для каждого дубликата ключа.
    // В качестве особого случая в Windows SYSTEMROOT всегда добавляется, если
    // отсутствует и явно не установлен в пустую строку.
    //
    // См. также поле Dir, которое может устанавливать PWD в среде.
    Env []string

    // Dir указывает рабочий каталог команды.
	// Если Dir является пустой строкой, Run запускает команду в
    // текущем каталоге вызывающего процесса.
    //
    // В системах Unix значение Dir также определяет
    // переменную окружения PWD дочернего процесса, если не указано иное
    //. Процесс Unix представляет свой рабочий каталог
    // не по имени, а как неявную ссылку на узел в
	// дереве файлов. Таким образом, если дочерний процесс получает свой рабочий
    // каталог путем вызова функции, такой как getcwd в C, которая
    // вычисляет каноническое имя, проходя по дереву файлов, он
    // не восстановит исходное значение Dir, если это значение
    // было псевдонимом, включающим символьные ссылки. Однако, если
    // дочерний процесс вызывает [os.Getwd] в Go или
	// get_current_dir_name из GNU C, и значение PWD является псевдонимом для
    // текущего каталога, эти функции вернут
    // значение PWD, которое совпадает со значением Dir.
    Dir string

    // Stdin указывает стандартный ввод процесса.
    //
    // Если Stdin равно nil, процесс читает из нулевого устройства (os.DevNull).
    //
	// Если Stdin является *os.File, стандартный ввод процесса подключается
    // непосредственно к этому файлу.
    //
    // В противном случае во время выполнения команды отдельная
    // goroutine считывает данные из Stdin и передает их команде
    // через канал. В этом случае Wait не завершается, пока goroutine
    // не прекратит копирование, либо потому что достиг конца Stdin
	// (EOF или ошибка чтения), либо потому, что запись в канал вернула ошибку,
    // либо потому, что было установлено ненулевое значение WaitDelay, которое истекло.
    Stdin io.Reader

    // Stdout и Stderr указывают стандартный вывод и ошибки процесса.
    //
    // Если любой из них равен nil, Run подключает соответствующий файловый дескриптор
    // к нулевому устройству (os.DevNull).
	//
    // Если любой из них является *os.File, соответствующий вывод из процесса
    // подключается непосредственно к этому файлу.
    //
    // В противном случае во время выполнения команды отдельная goroutine
    // считывает данные из процесса через канал и доставляет их в
    // соответствующий Writer. В этом случае Wait не завершается, пока
    // goroutine не достигнет EOF, не столкнется с ошибкой или не истечет ненулевое значение WaitDelay
	//.
    //
    // Если Stdout и Stderr являются одним и тем же writer и имеют тип, который можно
    // сравнить с помощью ==, то одновременно Write будет вызывать не более одного goroutine.
    Stdout io.Writer
    Stderr io.Writer

    // ExtraFiles указывает дополнительные открытые файлы, которые будут унаследованы
	// новый процесс. Он не включает стандартный ввод, стандартный вывод или
    // стандартную ошибку. Если не равен nil, запись i становится файловым дескриптором 3+i.
    //
    // ExtraFiles не поддерживается в Windows.
    ExtraFiles []*os.File

    // SysProcAttr содержит дополнительные атрибуты, специфичные для операционной системы.
	// Run передает его os.StartProcess как поле Sys os.ProcAttr.
    SysProcAttr *syscall.SysProcAttr

    // Process — это базовый процесс после запуска.
    Process *os.Process

    // ProcessState содержит информацию о завершенном процессе.
    // Если процесс был запущен успешно, Wait или Run
	// заполнят его ProcessState по завершении команды.
    ProcessState *os.ProcessState

    Err error // Ошибка LookPath, если есть.

    // Если Cancel не равен nil, команда должна быть создана с помощью
    // CommandContext, и Cancel будет вызван, когда
    // Context команды будет выполнен. По умолчанию CommandContext устанавливает Cancel в
	// вызывает метод Kill в процессе команды.
    //
    // Обычно пользовательский Cancel посылает сигнал процессу команды
    //, но вместо этого он может предпринять другие действия для инициирования отмены,
    // такие как закрытие канала stdin или stdout или отправка запроса на завершение работы
    // сетевого сокета.
    //
	// Если команда завершается с успешным статусом после вызова Cancel
    //, а Cancel не возвращает ошибку, эквивалентную
    // os.ErrProcessDone, то Wait и подобные методы будут возвращать не нулевую
    // ошибку: либо ошибку, оборачивающую ошибку, возвращенную Cancel,
    // либо ошибку из Context.
    // (Если команда завершается с неуспешным статусом или Cancel
	// возвращает ошибку, которая оборачивает os.ErrProcessDone, Wait и подобные методы
    // продолжают возвращать обычный статус завершения команды.)
    //
    // Если Cancel установлен в nil, ничего не произойдет сразу после завершения
    // Context команды, но WaitDelay, отличное от нуля, все равно будет действовать. Это может
    // быть полезно, например, для обхода тупиковых ситуаций в командах, которые не
	// поддерживают сигналы завершения, но должны всегда завершаться быстро.
    //
    // Cancel не будет вызван, если Start возвращает ошибку, отличную от nil.
    Cancel func() error
    // Если WaitDelay отлично от нуля, оно ограничивает время ожидания двух источников
    // непредвиденной задержки в Wait: дочернего процесса, который не завершается после
    // отмены связанного Context, и дочернего процесса, который завершается, но оставляет
	// свои каналы ввода-вывода незакрытыми.
    //
    // Таймер WaitDelay запускается, когда связанный контекст завершается или
    // вызов Wait обнаруживает, что дочерний процесс завершился, в зависимости от того, что произойдет
    // первым. По истечении задержки команда завершает дочерний процесс
    // и/или его каналы ввода-вывода.
    //
	// Если дочерний процесс не завершился — возможно, потому что он проигнорировал или
    // не получил сигнал о завершении от функции Cancel, или потому что не была
    // установлена функция Cancel — то он будет завершен с помощью os.Process.Kill.
    //
    // Затем, если каналы ввода-вывода, связывающиеся с дочерним процессом, все еще открыты,
    // эти каналы закрываются, чтобы разблокировать все goroutines, которые в данный момент заблокированы
	// вызовами Read или Write.
    //
    // Если трубы закрыты из-за WaitDelay, вызов Cancel не произошел,
    // и команда завершилась с успешным статусом, Wait и
    // подобные методы вернут ErrWaitDelay вместо nil.
    //
    // Если WaitDelay равен нулю (по умолчанию), трубы ввода-вывода будут читаться до EOF,
	// что может не произойти, пока осиротевшие подпроцессы команды
    // также не закроют свои дескрипторы для каналов.
    WaitDelay time.Duration
    // содержит отфильтрованные или неэкспортированные поля
}

Cmd представляет внешнюю команду, которая готовится или запускается.

Cmd не может быть повторно использован после вызова методов Cmd.Run, Cmd.Output или Cmd.CombinedOutput.

func Command

func Command(name string, arg ...string) *Cmd

Command возвращает структуру Cmd для выполнения именованной программы с заданными аргументами.

В возвращаемой структуре задаются только Path и Args.

Если имя не содержит разделителей путей, Command использует LookPath для преобразования имени в полный путь, если это возможно. В противном случае она использует имя непосредственно в качестве Path.

Возвращаемое поле Args Cmd строится из имени команды, за которым следуют элементы arg, поэтому arg не должно включать само имя команды. Например, Command(“echo”, “hello”). Args[0] - это всегда имя, а не возможно разрешенный Path.

В Windows процессы получают всю командную строку как единую строку и выполняют собственный разбор. Command объединяет и заключает Args в кавычки в строку командной строки с помощью алгоритма, совместимого с приложениями, использующими CommandLineToArgvW (это наиболее распространенный способ). Заметными исключениями являются msiexec.exe и cmd.exe (и, соответственно, все пакетные файлы), которые имеют другой алгоритм снятия кавычек. В этих и других подобных случаях вы можете выполнить котирование самостоятельно и указать полную командную строку в SysProcAttr.CmdLine, оставив Args пустым.

Пример
package main

import (
	"fmt"
	"log"
	"os/exec"
	"strings"
)

func main() {
	cmd := exec.Command("tr", "a-z", "A-Z")
	cmd.Stdin = strings.NewReader("some input")
	var out strings.Builder
	cmd.Stdout = &out
	err := cmd.Run()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("in all caps: %q\n", out.String())
}
Пример с окружением среды
package main

import (
	"log"
	"os"
	"os/exec"
)

func main() {
	cmd := exec.Command("prog")
	cmd.Env = append(os.Environ(),
		"FOO=duplicate_value", // ignored
		"FOO=actual_value",    // this value is used
	)
	if err := cmd.Run(); err != nil {
		log.Fatal(err)
	}
}

func CommandContext

func CommandContext(ctx context.Context, name string, arg ...string) *Cmd

CommandContext похож на Command, но включает в себя контекст.

Предоставленный контекст используется для прерывания процесса (путем вызова cmd.Cancel или os.Process.Kill), если контекст завершается до того, как команда завершит свою работу.

CommandContext устанавливает функцию Cancel команды для вызова метода Kill в ее Process и оставляет WaitDelay не установленным. Вызывающая сторона может изменить поведение отмены, изменив эти поля перед запуском команды.

Пример
package main

import (
	"context"
	"os/exec"
	"time"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
	defer cancel()

	if err := exec.CommandContext(ctx, "sleep", "5").Run(); err != nil {
		// This will fail after 100 milliseconds. The 5 second sleep
		// will be interrupted.
	}
}

func (*Cmd) CombinedOutput

func (c *Cmd) CombinedOutput() ([]byte, error)

CombinedOutput запускает команду и возвращает ее объединенный стандартный вывод и стандартную ошибку.

Пример
package main

import (
	"fmt"
	"log"
	"os/exec"
)

func main() {
	cmd := exec.Command("sh", "-c", "echo stdout; echo 1>&2 stderr")
	stdoutStderr, err := cmd.CombinedOutput()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", stdoutStderr)
}

func (*Cmd) Environ

func (c *Cmd) Environ() []string

Environ возвращает копию среды, в которой будет запущена команда, в том виде, в котором она настроена в данный момент.

Пример
package main

import (
	"fmt"
	"log"
	"os/exec"
)

func main() {
	cmd := exec.Command("pwd")

	// Set Dir before calling cmd.Environ so that it will include an
	// updated PWD variable (on platforms where that is used).
	cmd.Dir = ".."
	cmd.Env = append(cmd.Environ(), "POSIXLY_CORRECT=1")

	out, err := cmd.Output()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s\n", out)
}

func (*Cmd) Output

func (c *Cmd) Output() ([]byte, error)

Output запускает команду и возвращает ее стандартный вывод. Любая возвращаемая ошибка обычно будет иметь тип *ExitError. Если c.Stderr было nil, а возвращаемая ошибка имеет тип *ExitError, Output заполняет поле Stderr возвращаемой ошибки.

Пример
package main

import (
	"fmt"
	"log"
	"os/exec"
)

func main() {
	out, err := exec.Command("date").Output()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("The date is %s\n", out)
}

func (*Cmd) Run

func (c *Cmd) Run() error

Run запускает указанную команду и ждет ее завершения.

Возвращаемая ошибка равна nil, если команда запущена, не возникло проблем с копированием stdin, stdout и stderr, и она завершилась с нулевым статусом выхода.

Если команда запущена, но не завершилась успешно, ошибка будет типа *ExitError. В других ситуациях могут возвращаться ошибки других типов.

Если вызывающая goroutine заблокировала поток операционной системы с помощью runtime.LockOSThread и изменила любое наследуемое состояние потока на уровне ОС (например, пространства имен Linux или Plan 9), новый процесс унаследует состояние потока вызывающего.

Пример
package main

import (
	"log"
	"os/exec"
)

func main() {
	cmd := exec.Command("sleep", "1")
	log.Printf("Running command and waiting for it to finish...")
	err := cmd.Run()
	log.Printf("Command finished with error: %v", err)
}

func (*Cmd) Start

func (c *Cmd) Start() error

Start запускает указанную команду, но не ждет ее завершения.

Если Start возвращается успешно, поле c.Process будет установлено.

После успешного вызова Start необходимо вызвать метод Cmd.Wait, чтобы освободить связанные системные ресурсы.

Пример
package main

import (
	"log"
	"os/exec"
)

func main() {
	cmd := exec.Command("sleep", "5")
	err := cmd.Start()
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("Waiting for command to finish...")
	err = cmd.Wait()
	log.Printf("Command finished with error: %v", err)
}

func (*Cmd) StderrPipe

func (c *Cmd) StderrPipe() (io.ReadCloser, error)

StderrPipe возвращает канал, который будет подключен к стандартной ошибке команды при ее запуске.

Cmd.Wait закроет канал после завершения команды, поэтому большинству вызывающих не нужно закрывать канал самостоятельно. Таким образом, неправильно вызывать Wait до завершения всех операций чтения из канала. По той же причине неправильно использовать Cmd.Run при использовании StderrPipe. Идиоматическое использование см. в примере StdoutPipe.

Пример
package main

import (
	"fmt"
	"io"
	"log"
	"os/exec"
)

func main() {
	cmd := exec.Command("sh", "-c", "echo stdout; echo 1>&2 stderr")
	stderr, err := cmd.StderrPipe()
	if err != nil {
		log.Fatal(err)
	}

	if err := cmd.Start(); err != nil {
		log.Fatal(err)
	}

	slurp, _ := io.ReadAll(stderr)
	fmt.Printf("%s\n", slurp)

	if err := cmd.Wait(); err != nil {
		log.Fatal(err)
	}
}

func (*Cmd) StdinPipe

func (c *Cmd) StdinPipe() (io.WriteCloser, error)

StdinPipe возвращает канал, который будет подключен к стандартному входу команды при ее запуске. Канал будет автоматически закрыт после того, как Cmd.Wait увидит выход команды. Вызывающему достаточно вызвать Close, чтобы заставить канал закрыться раньше. Например, если запускаемая команда не завершится до закрытия стандартного ввода, вызывающий должен закрыть канал.

Пример
package main

import (
	"fmt"
	"io"
	"log"
	"os/exec"
)

func main() {
	cmd := exec.Command("cat")
	stdin, err := cmd.StdinPipe()
	if err != nil {
		log.Fatal(err)
	}

	go func() {
		defer stdin.Close()
		io.WriteString(stdin, "values written to stdin are passed to cmd's standard input")
	}()

	out, err := cmd.CombinedOutput()
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s\n", out)
}

func (*Cmd) StdoutPipe

func (c *Cmd) StdoutPipe() (io.ReadCloser, error)

StdoutPipe возвращает канал, который будет подключен к стандартному выводу команды при ее запуске.

Cmd.Wait закроет канал после завершения команды, поэтому большинству вызывающих не нужно закрывать канал самостоятельно. Таким образом, неправильно вызывать Wait до завершения всех операций чтения из канала. По той же причине неправильно вызывать Cmd.Run при использовании StdoutPipe. См. пример для идиоматического использования.

Пример
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"os/exec"
)

func main() {
	cmd := exec.Command("echo", "-n", `{"Name": "Bob", "Age": 32}`)
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal(err)
	}
	if err := cmd.Start(); err != nil {
		log.Fatal(err)
	}
	var person struct {
		Name string
		Age  int
	}
	if err := json.NewDecoder(stdout).Decode(&person); err != nil {
		log.Fatal(err)
	}
	if err := cmd.Wait(); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s is %d years old\n", person.Name, person.Age)

func (*Cmd) String

func (c *Cmd) String() string

String возвращает удобочитаемое описание c. Предназначено только для отладки. В частности, не подходит для использования в качестве ввода в оболочку. Вывод String может различаться в разных версиях Go.

func (*Cmd) Wait

func (c *Cmd) Wait() error

Wait ожидает завершения команды и завершения копирования в stdin или копирования из stdout или stderr.

Команда должна быть запущена с помощью Cmd.Start.

Возвращаемая ошибка равна nil, если команда запущена, не имеет проблем с копированием stdin, stdout и stderr и завершается с нулевым статусом выхода.

Если команда не запускается или не завершается успешно, ошибка имеет тип *ExitError. Другие типы ошибок могут возвращаться при проблемах с вводом-выводом.

Если c.Stdin, c.Stdout или c.Stderr не являются *os.File, Wait также ожидает завершения соответствующего цикла ввода-вывода в процесс или из процесса.

Wait освобождает все ресурсы, связанные с Cmd.

type Error

type Error struct {
    // Name — имя файла, для которого произошла ошибка.
    Name string
    // Err — базовая ошибка.
    Err error
}

Error возвращается LookPath, когда он не может классифицировать файл как исполняемый.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Unwrap

func (e *Error) Unwrap() error

type ExitError

type ExitError struct {
    *os.ProcessState

    // Stderr содержит подмножество стандартного вывода ошибок из
    // метода Cmd.Output, если стандартные ошибки не были
    // собраны иным способом.
    //
    // Если вывод ошибок длинный, Stderr может содержать только префикс
	// и суффикс вывода, а середина будет заменена
    // текстом о количестве пропущенных байтов.
    //
    // Stderr предоставляется для отладки, для включения в сообщения об ошибках.
    // Пользователи с другими потребностями должны перенаправить Cmd.Stderr по мере необходимости.
    Stderr []byte
}

ExitError сообщает о неудачном завершении команды.

func (*ExitError) Error

func (e *ExitError) Error() string

4 - Пакет os/user языка программирования Go

Пакет user позволяет искать учетные записи пользователей по имени или идентификатору.

Для большинства систем Unix этот пакет имеет две внутренние реализации преобразования идентификаторов пользователей и групп в имена, а также вывода списка дополнительных идентификаторов групп. Одна из них написана на чистом Go и анализирует файлы /etc/passwd и /etc/group. Другая основана на cgo и использует стандартные процедуры библиотеки C (libc), такие как getpwuid_r, getgrnam_r и getgrouplist.

Если cgo доступен, а необходимые процедуры реализованы в libc для конкретной платформы, используется код на основе cgo (с поддержкой libc). Это можно переопределить с помощью тега сборки osusergo, который принудительно использует реализацию на чистом Go.

type Group

type Group struct {
    Gid  string // идентификатор группы
    Name string // название группы
}

Group представляет группу пользователей.

В системах POSIX Gid содержит десятичное число, представляющее идентификатор группы.

func LookupGroup

func LookupGroup(name string) (*Group, error)

LookupGroup ищет группу по имени. Если группа не найдена, возвращается ошибка типа UnknownGroupError.

func LookupGroupId

func LookupGroupId(gid string) (*Group, error)

LookupGroupId ищет группу по groupid. Если группа не найдена, возвращается ошибка типа UnknownGroupIdError.

type UnknownGroupError

type UnknownGroupError string

UnknownGroupError возвращается LookupGroup, когда группа не может быть найдена.

func (UnknownGroupError) Error

func (e UnknownGroupError) Error() string

type UnknownGroupIdError

type UnknownGroupIdError string

UnknownGroupIdError возвращается LookupGroupId, когда группа не может быть найдена.

func (UnknownGroupIdError) Error

func (e UnknownGroupIdError) Error() string

type UnknownUserError

type UnknownUserError string

UnknownUserError возвращается Lookup, когда пользователь не может быть найден.

func (UnknownUserError) Error

func (e UnknownUserError) Error() string

type UnknownUserIdError

type UnknownUserIdError int

UnknownUserIdError возвращается LookupId, когда пользователь не может быть найден.

func (UnknownUserIdError) Error

func (e UnknownUserIdError) Error() string

type User ¶

type User struct {
    // Uid — это идентификатор пользователя.
	// В системах POSIX это десятичное число, представляющее uid.
    // В Windows это идентификатор безопасности (SID) в формате строки.
    // В Plan 9 это содержимое /dev/user.
    Uid string
    // Gid — это идентификатор основной группы.
    // В системах POSIX это десятичное число, представляющее gid.
	// В Windows это SID в формате строки.
    // В Plan 9 это содержимое /dev/user.
    Gid string
    // Username — это имя для входа в систему.
    Username string
    // Name — это настоящее или отображаемое имя пользователя.
    // Оно может быть пустым.
    // В системах POSIX это первая (или единственная) запись в поле GECOS
	// списка GECOS.
    // В Windows это отображаемое имя пользователя.
    // В Plan 9 это содержимое /dev/user.
    Строка имени
    // HomeDir — это путь к домашнему каталогу пользователя (если он есть).
    Строка HomeDir
}

User представляет учетную запись пользователя.

func Current

func Current() (*User, error)

Current возвращает текущего пользователя.

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

func Lookup

func Lookup(username string) (*User, error)

Lookup ищет пользователя по имени. Если пользователь не найден, возвращается ошибка типа UnknownUserError.

func LookupId

func LookupId(uid string) (*User, error)

LookupId ищет пользователя по идентификатору. Если пользователь не найден, возвращается ошибка типа UnknownUserIdError.

func (*User) GroupIds

func (u *User) GroupIds() ([]string, error)

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

5 - Пакет os/signal языка программирования Go

Пакет signal реализует доступ к входящим сигналам.

Сигналы в основном используются в Unix-подобных системах. Для использования этого пакета в Windows и Plan 9 см. ниже.

Типы сигналов

Сигналы SIGKILL и SIGSTOP не могут быть перехвачены программой и, следовательно, не могут быть затронуты этим пакетом.

Синхронные сигналы — это сигналы, вызываемые ошибками при выполнении программы: SIGBUS, SIGFPE и SIGSEGV. Они считаются синхронными только в том случае, если вызваны выполнением программы, а не отправлены с помощью os.Process.Kill, программы kill или аналогичного механизма. В общем случае, за исключением описанного ниже, программы Go преобразуют синхронный сигнал в панику во время выполнения.

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

Из асинхронных сигналов сигнал SIGHUP отправляется, когда программа теряет свой управляющий терминал. Сигнал SIGINT отправляется, когда пользователь на управляющем терминале нажимает символ прерывания, который по умолчанию является ^C (Control-C). Сигнал SIGQUIT отправляется, когда пользователь на управляющем терминале нажимает символ выхода, который по умолчанию является ^\ (Control-Backslash). Как правило, вы можете просто завершить программу, нажав ^C, а также завершить ее с дампом стека, нажав ^.

Поведение сигналов по умолчанию в программах Go

По умолчанию синхронный сигнал преобразуется в панику во время выполнения. Сигнал SIGHUP, SIGINT или SIGTERM приводит к завершению программы. Сигнал SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGSTKFLT, SIGEMT или SIGSYS приводит к завершению программы с дампом стека. Сигнал SIGTSTP, SIGTTIN или SIGTTOU получает поведение по умолчанию системы (эти сигналы используются оболочкой для управления задачами). Сигнал SIGPROF обрабатывается непосредственно средой выполнения Go для реализации runtime.CPUProfile. Другие сигналы будут перехвачены, но никаких действий не будет предпринято.

Если программа Go запущена с игнорированием сигналов SIGHUP или SIGINT (обработчик сигналов установлен в SIG_IGN), они будут по-прежнему игнорироваться.

Если программа Go запущена с непустой маской сигналов, она, как правило, будет соблюдаться. Однако некоторые сигналы явно разблокированы: синхронные сигналы, SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF, а в Linux — сигналы 32 (SIGCANCEL) и 33 (SIGSETXID) (SIGCANCEL и SIGSETXID используются внутренне glibc). Подпроцессы, запущенные с помощью os.Exec или os/exec, унаследуют измененную маску сигналов.

Изменение поведения сигналов в программах Go

Функции в этом пакете позволяют программе изменять способ обработки сигналов программами Go.

Notify отключает поведение по умолчанию для заданного набора асинхронных сигналов и вместо этого доставляет их по одному или нескольким зарегистрированным каналам. В частности, это относится к сигналам SIGHUP, SIGINT, SIGQUIT, SIGABRT и SIGTERM. Это также относится к сигналам управления задачами SIGTSTP, SIGTTIN и SIGTTOU, в этом случае поведение по умолчанию системы не происходит. Она также применяется к некоторым сигналам, которые в противном случае не вызывают никаких действий: SIGUSR1, SIGUSR2, SIGPIPE, SIGALRM, SIGCHLD, SIGCONT, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGWINCH, SIGIO, SIGPWR, SIGINFO, SIGTHR, SIGWAITING, SIGLWP, SIGFREEZE, SIGTHAW, SIGLOST, SIGXRES, SIGJVM1, SIGJVM2 и любые сигналы реального времени, используемые в системе. Обратите внимание, что не все эти сигналы доступны во всех системах.

Если программа была запущена с игнорированием SIGHUP или SIGINT, и для любого из этих сигналов вызван Notify, для этого сигнала будет установлен обработчик сигналов, и он больше не будет игнорироваться. Если позже для этого сигнала вызван Reset или Ignore, или вызван Stop для всех каналов, переданных Notify для этого сигнала, сигнал снова будет игнорироваться. Reset восстановит поведение системы по умолчанию для сигнала, а Ignore заставит систему полностью игнорировать сигнал.

Если программа запущена с непустой маской сигналов, некоторые сигналы будут явно разблокированы, как описано выше. Если Notify вызывается для заблокированного сигнала, он будет разблокирован. Если позже для этого сигнала вызывается Reset или Stop для всех каналов, переданных Notify для этого сигнала, сигнал снова будет заблокирован.

SIGPIPE

Когда программа на Go записывает в разорванный канал, ядро генерирует сигнал SIGPIPE.

Если программа не вызвала Notify для получения сигналов SIGPIPE, то поведение зависит от номера файлового дескриптора. Запись в разорванный канал на файловых дескрипторах 1 или 2 (стандартный вывод или стандартная ошибка) приведет к завершению программы с сигналом SIGPIPE. Запись в разорванный канал на каком-либо другом файловом дескрипторе не вызовет никаких действий по сигналу SIGPIPE, и запись завершится с ошибкой EPIPE.

Если программа вызвала Notify для получения сигналов SIGPIPE, номер файлового дескриптора не имеет значения. Сигнал SIGPIPE будет доставлен в канал Notify, и запись завершится с ошибкой EPIPE.

Это означает, что по умолчанию программы командной строки будут вести себя как типичные программы командной строки Unix, в то время как другие программы не будут завершаться с SIGPIPE при записи в закрытое сетевое соединение.

Программы Go, использующие cgo или SWIG

В программе Go, которая включает код, не относящийся к Go, обычно код C/C++, доступ к которому осуществляется с помощью cgo или SWIG, сначала запускается код запуска Go. Он настраивает обработчики сигналов в соответствии с ожиданиями среды выполнения Go, прежде чем запускается код запуска, не относящийся к Go. Если код запуска, не относящийся к Go, желает установить свои собственные обработчики сигналов, он должен предпринять определенные шаги, чтобы Go продолжал работать нормально. В этом разделе описаны эти шаги и общие изменения, которые могут быть внесены в настройки обработчиков сигналов кодом, не относящимся к Go, в программах Go. В редких случаях код, не относящийся к Go, может запускаться перед кодом Go, и в этом случае также применяется следующий раздел.

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

Если код, не относящийся к Go, устанавливает какие-либо обработчики сигналов, он должен использовать флаг SA_ONSTACK с sigaction. Невыполнение этого требования может привести к сбою программы при получении сигнала. Программы Go обычно работают с ограниченным стеком, поэтому настраивают альтернативный стек сигналов.

Если код, не относящийся к Go, устанавливает обработчик сигналов для любого из синхронных сигналов (SIGBUS, SIGFPE, SIGSEGV), то он должен записывать существующий обработчик сигналов Go. Если эти сигналы возникают во время выполнения кода Go, он должен вызывать обработчик сигналов Go (возникновение сигнала во время выполнения кода Go можно определить, посмотрев на PC, передаваемый обработчику сигналов). В противном случае некоторые паники времени выполнения Go не будут происходить, как ожидается.

Если код, не относящийся к Go, устанавливает обработчик сигналов для любого из асинхронных сигналов, он может вызывать обработчик сигналов Go или нет, по своему усмотрению. Естественно, если он не вызывает обработчик сигналов Go, описанное выше поведение Go не будет происходить. Это может быть проблемой, в частности, с сигналом SIGPROF.

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

Если код, не относящийся к Go, запускает новый поток, изменяет маску сигналов, а затем вызывает функцию Go в этом потоке, среда выполнения Go автоматически разблокирует определенные сигналы: синхронные сигналы, SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF, SIGCANCEL и SIGSETXID. Когда функция Go возвращается, маска сигналов, не относящаяся к Go, будет восстановлена.

Если обработчик сигналов Go вызывается в потоке, не относящемся к Go и не выполняющем код Go, обработчик обычно пересылает сигнал в код, не относящийся к Go, следующим образом. Если сигнал является SIGPROF, обработчик Go ничего не делает. В противном случае обработчик Go удаляет себя, разблокирует сигнал и снова его генерирует, чтобы вызвать любой обработчик, не относящийся к Go, или системный обработчик по умолчанию. Если программа не завершается, обработчик Go переустанавливает себя и продолжает выполнение программы.

Если получен сигнал SIGPIPE, программа Go вызовет специальную обработку, описанную выше, если SIGPIPE получен в потоке Go. Если SIGPIPE получен в потоке, не относящемся к Go, сигнал будет перенаправлен в обработчик, не относящийся к Go, если таковой имеется; если его нет, обработчик по умолчанию системы приведет к завершению программы.

Программы, не написанные на Go, которые вызывают код Go

Когда код Go компилируется с такими опциями, как -buildmode=c-shared, он будет запускаться как часть существующей программы, не написанной на Go. Код, не написанный на Go, может уже иметь установленные обработчики сигналов, когда запускается код Go (это также может произойти в необычных случаях при использовании cgo или SWIG; в этом случае применимо обсуждение, приведенное здесь). Для -buildmode=c-archive среда выполнения Go инициализирует сигналы во время глобального конструктора. Для -buildmode=c-shared среда выполнения Go инициализирует сигналы при загрузке разделяемой библиотеки.

Если среда выполнения Go обнаруживает существующий обработчик сигналов для сигналов SIGCANCEL или SIGSETXID (которые используются только в Linux), она включает флаг SA_ONSTACK и в остальном сохраняет обработчик сигналов.

Для синхронных сигналов и SIGPIPE среда выполнения Go установит обработчик сигналов. Она сохранит любой существующий обработчик сигналов. Если синхронный сигнал поступает во время выполнения кода, не относящегося к Go, среда выполнения Go вызовет существующий обработчик сигналов вместо обработчика сигналов Go.

Код Go, скомпилированный с -buildmode=c-archive или -buildmode=c-shared, по умолчанию не будет устанавливать никаких других обработчиков сигналов. Если существующий обработчик сигналов, среда выполнения Go включит флаг SA_ONSTACK и сохранит обработчик сигналов. Если Notify вызывается для асинхронного сигнала, для этого сигнала будет установлен обработчик сигналов Go. Если позже для этого сигнала вызывается Reset, исходная обработка этого сигнала будет переустановлена, восстанавливая обработчик сигналов, не относящийся к Go, если таковой имеется.

Код Go, скомпилированный без -buildmode=c-archive или -buildmode=c-shared, установит обработчик сигналов для асинхронных сигналов, перечисленных выше, и сохранит любой существующий обработчик сигналов. Если сигнал доставляется в поток, не относящийся к Go, он будет действовать, как описано выше, за исключением того, что если существует обработчик сигналов, не относящийся к Go, этот обработчик будет установлен перед генерацией сигнала. Windows ¶

В Windows ^C (Control-C) или ^BREAK (Control-Break) обычно приводят к завершению программы. Если Notify вызывается для os.Interrupt, ^C или ^BREAK приводят к отправке os.Interrupt по каналу, и программа не завершается. Если вызывается Reset или Stop на всех каналах, переданных Notify, то поведение по умолчанию будет восстановлено.

Кроме того, если вызывается Notify, и Windows отправляет CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT или CTRL_SHUTDOWN_EVENT процессу, Notify вернет syscall.SIGTERM. В отличие от Control-C и Control-Break, Notify не изменяет поведение процесса при получении CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT или CTRL_SHUTDOWN_EVENT — процесс все равно будет завершен, если он не завершится самостоятельно. Но получение syscall.SIGTERM даст процессу возможность очиститься перед завершением.

Plan 9

В Plan 9 сигналы имеют тип syscall.Note, который представляет собой строку. Вызов Notify с syscall.Note приведет к отправке этого значения по каналу, когда эта строка будет отправлена в качестве заметки.

Функции

func Ignore

func Ignore(sig ...os.Signal)

Ignore заставляет игнорировать указанные сигналы. Если они будут получены программой, ничего не произойдет. Ignore отменяет действие всех предыдущих вызовов Notify для указанных сигналов. Если сигналы не указаны, все входящие сигналы будут игнорироваться.

func Ignored

func Ignored(sig os.Signal) bool

Ignored сообщает, игнорируется ли sig в данный момент.

func Notify

func Notify(c chan<- os.Signal, sig ...os.Signal)

Notify заставляет пакет signal ретранслировать входящие сигналы в c. Если сигналы не предоставлены, все входящие сигналы будут ретранслированы в c. В противном случае будут ретранслированы только предоставленные сигналы.

Пакет signal не будет блокировать отправку в c: вызывающий должен убедиться, что c имеет достаточное буферное пространство, чтобы справиться с ожидаемой скоростью сигналов. Для канала, используемого для уведомления только об одном значении сигнала, достаточно буфера размером 1.

Разрешается вызывать Notify несколько раз с одним и тем же каналом: каждый вызов расширяет набор сигналов, отправляемых на этот канал. Единственный способ удалить сигналы из набора — вызвать Stop.

Разрешается вызывать Notify несколько раз с разными каналами и одними и теми же сигналами: каждый канал получает копии входящих сигналов независимо.

Пример
package main

import (
	"fmt"
	"os"
	"os/signal"
)

func main() {
	// Set up channel on which to send signal notifications.
	// We must use a buffered channel or risk missing the signal
	// if we're not ready to receive when the signal is sent.
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)

	// Block until a signal is received.
	s := <-c
	fmt.Println("Got signal:", s)
}
Пример AllSignals
package main

import (
	"fmt"
	"os"
	"os/signal"
)

func main() {
	// Set up channel on which to send signal notifications.
	// We must use a buffered channel or risk missing the signal
	// if we're not ready to receive when the signal is sent.
	c := make(chan os.Signal, 1)

	// Passing no signals to Notify means that
	// all signals will be sent to the channel.
	signal.Notify(c)

	// Block until any signal is received.
	s := <-c
	fmt.Println("Got signal:", s)
}

func NotifyContext

func NotifyContext(parent context.Context, signals ...os.Signal) (ctx context.Context, stop context.CancelFunc)

NotifyContext возвращает копию родительского контекста, который помечается как выполненный (его канал Done закрывается), когда поступает один из перечисленных сигналов, когда вызывается возвращаемая функция stop или когда канал Done родительского контекста закрывается, в зависимости от того, что произойдет раньше.

Функция stop отменяет регистрацию поведения сигнала, что, как и signal.Reset, может восстановить поведение по умолчанию для данного сигнала. Например, поведением по умолчанию для программы Go, получающей os.Interrupt, является выход. Вызов NotifyContext(parent, os.Interrupt) изменит поведение на отмену возвращенного контекста. Будущие прерывания не будут вызывать поведение по умолчанию (выход) до тех пор, пока не будет вызвана возвращенная функция stop.

Функция stop освобождает связанные с ней ресурсы, поэтому код должен вызывать stop, как только операции, выполняемые в этом контексте, завершатся и сигналы больше не нужно будет перенаправлять в контекст.

Пример
//go:build unix

package main

import (
	"context"
	"fmt"
	"log"
	"os"
	"os/signal"
)

var neverReady = make(chan struct{}) // never closed

// This example passes a context with a signal to tell a blocking function that
// it should abandon its work after a signal is received.
func main() {
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()

	p, err := os.FindProcess(os.Getpid())
	if err != nil {
		log.Fatal(err)
	}

	// On a Unix-like system, pressing Ctrl+C on a keyboard sends a
	// SIGINT signal to the process of the program in execution.
	//
	// This example simulates that by sending a SIGINT signal to itself.
	if err := p.Signal(os.Interrupt); err != nil {
		log.Fatal(err)
	}

	select {
	case <-neverReady:
		fmt.Println("ready")
	case <-ctx.Done():
		fmt.Println(ctx.Err()) // prints "context canceled"
		stop()                 // stop receiving signal notifications as soon as possible.
	}

}
Output:

context canceled

func Reset

func Reset(sig ...os.Signal)

Reset отменяет эффект всех предыдущих вызовов Notify для предоставленных сигналов. Если сигналы не указаны, все обработчики сигналов будут сброшены.

func Stop

func Stop(c chan<- os.Signal)

Stop заставляет пакет signal прекратить ретрансляцию входящих сигналов в c. Он отменяет эффект всех предыдущих вызовов Notify с использованием c. Когда Stop возвращается, гарантируется, что c больше не будет получать сигналы.