Пакет 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 (
SEEK_SET int = 0 // поиск относительно начала файла
SEEK_CUR int = 1 // поиск относительно текущего смещения
SEEK_END int = 2 // поиск относительно конца
)
Значения поиска.
Устарело: используйте io.SeekStart, io.SeekCurrent и io.SeekEnd.
Просмотреть исходный код
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 может привести к тому, что эти сообщения будут отправляться в другое место, например в файл, открытый позже.
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
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
Environ возвращает копию строк, представляющих среду, в форме «ключ=значение».
func Executable
func Executable() (string, error)
Executable возвращает имя пути к исполняемому файлу, который запустил текущий процесс. Нет гарантии, что путь по-прежнему указывает на правильный исполняемый файл. Если для запуска процесса использовалась символьная ссылка, в зависимости от операционной системы результатом может быть символьная ссылка или путь, на который она указывала. Если требуется стабильный результат, может помочь path/filepath.EvalSymlinks.
Executable возвращает абсолютный путь, если не произошла ошибка.
Основной случай использования — поиск ресурсов, расположенных относительно исполняемого файла.
func Exit
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
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
Geteuid возвращает числовой эффективный идентификатор пользователя вызывающего.
В Windows возвращает -1.
func Getgid
Getgid возвращает числовой идентификатор группы вызывающего.
В Windows возвращает -1.
func Getgroups
func Getgroups() ([]int, error)
Getgroups возвращает список числовых идентификаторов групп, к которым принадлежит вызывающий.
В Windows возвращает syscall.EWINDOWS. Возможную альтернативу см. в пакете os/user.
func Getpagesize
Getpagesize возвращает размер страницы памяти базовой системы.
func Getpid
Getpid возвращает идентификатор процесса вызывающего.
func Getppid
Getppid возвращает идентификатор процесса родителя вызывающего.
func Getuid
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
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)
}
func Readlink
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
func Symlink(oldname, newname string) error
Symlink создает newname как символическую ссылку на oldname. В Windows символическая ссылка на несуществующий oldname создает файловую символическую ссылку; если oldname позже будет создан как каталог, символическая ссылка не будет работать. Если произойдет ошибка, она будет типа *LinkError.
func TempDir
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.
}
}
func Reset
func Reset(sig ...os.Signal)
Reset отменяет эффект всех предыдущих вызовов Notify для предоставленных сигналов. Если сигналы не указаны, все обработчики сигналов будут сброшены.
func Stop
func Stop(c chan<- os.Signal)
Stop заставляет пакет signal прекратить ретрансляцию входящих сигналов в c. Он отменяет эффект всех предыдущих вызовов Notify с использованием c. Когда Stop возвращается, гарантируется, что c больше не будет получать сигналы.