std/osproc
SourceEditЭтот модуль реализует расширенные возможности для запуска процессов ОС и взаимодействия между процессами.
См. также:
Импорты
- strutils, os, strtabs, streams, cpuinfo, streamwrapper, since, winlean
Типы
ProcessOption = enum poEchoCmd, ## Echo the command before execution. poUsePath, ## Asks system to search for executable using PATH environment ## variable. ## On Windows, this is the default. poEvalCommand, ## Pass `command` directly to the shell, without quoting. ## Use it only if `command` comes from trusted source. poStdErrToStdOut, ## Merge stdout and stderr to the stdout stream. poParentStreams, ## Use the parent's streams. poInteractive, ## Optimize the buffer handling for responsiveness for ## UI applications. Currently this only affects ## Windows: Named pipes are used so that you can peek ## at the process' output streams. poDaemon ## Windows: The program creates no Window. ## Unix: Start the program as a daemon. This is still ## work in progress!- Параметры, которые можно передать процедуре startProcess proc. Source Edit
Процедуры
proc close(p: Process) {....gcsafe, extern: "nosp$1", raises: [IOError, OSError], tags: [WriteIOEffect], forbids: [].}- Когда процесс завершил выполнение, очищает связанные дескрипторы.Предупреждение: Если процесс не завершил выполнение, это принудительно завершит процесс. Это может привести к появлению процессов-зомби и утечкам pty.Исходный код Изменить
proc countProcessors(): int {....gcsafe, extern: "nosp$1", raises: [], tags: [], forbids: [].}- Возвращает количество процессоров/ядер в машине. Возвращает 0, если количество не может быть определено. Реализовано с помощью вызова
cpuinfo.countProcessors. Исходный код Изменить proc errorHandle(p: Process): FileHandle {....gcsafe, extern: "nosp$1", raises: [], tags: [], forbids: [].}- Возвращает дескриптор файла ошибок
pдля чтения.Предупреждение: ВозвращённыйFileHandleне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Изменить proc errorStream(p: Process): Stream {....gcsafe, extern: "nosp$1", tags: [], raises: [], forbids: [].}-
Возвращает поток ошибок
pдля чтения.Вы не можете выполнять операции peek/write/setOption с этим потоком. Используйте процедуру peekableErrorStream, если вам нужно просмотреть поток.
Предупреждение: ВозвращённыйStreamне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Изменить proc execCmd(command: string): int {....gcsafe, extern: "nosp$1", tags: [ ExecIOEffect, ReadIOEffect, RootEffect], raises: [OSError], forbids: [].}-
Выполняет
commandи возвращает его код ошибки.Стандартные потоки ввода, вывода и ошибок наследуются от вызывающего процесса. Эта операция также часто называется system.
См. также:
Пример:
let errC = execCmd("nim c -r mytestfile.nim")Исходный код Изменить proc execCmdEx(command: string; options: set[ProcessOption] = {poStdErrToStdOut, poUsePath}; env: StringTableRef = nil; workingDir = ""; input = ""): tuple[ output: string, exitCode: int] {....raises: [OSError, IOError], tags: [ ExecIOEffect, ReadIOEffect, RootEffect], gcsafe, forbids: [].}-
Удобная процедура для запуска
command, и возвращает егоoutputиexitCode.envиworkingDirпараметры ведут себя аналогично параметрамstartProcess. Еслиinput.len > 0, он передаётся как stdin.Примечание: это может заблокировать выполнение, если
input.lenпревышает максимальный размер буфера канала вашей ОС.См. также:
Пример:
var result = execCmdEx("nim r --hints:off -", options = {}, input = "echo 3*4") import std/[strutils, strtabs] stripLineEnd(result[0]) ## portable way to remove trailing newline, if any doAssert result == ("12", 0) doAssert execCmdEx("ls --nonexistent").exitCode != 0 when defined(posix): assert execCmdEx("echo $FO", env = newStringTable({"FO": "B"})) == ("B\n", 0) assert execCmdEx("echo $PWD", workingDir = "/") == ("/\n", 0)Исходный код Изменить proc execProcess(command: string; workingDir: string = ""; args: openArray[string] = []; env: StringTableRef = nil; options: set[ProcessOption] = {poStdErrToStdOut, poUsePath, poEvalCommand}): string {. ...gcsafe, extern: "nosp$1", raises: [OSError, IOError], tags: [ExecIOEffect, ReadIOEffect, RootEffect], forbids: [].}- Удобная процедура, которая выполняет
commandсstartProcessи возвращает её вывод как строку.Предупреждение: Эта функция по умолчанию используетpoEvalCommandдля обеспечения обратной совместимости. Убедитесь, что явно передаёте опции.См. также:
Пример:
let outp = execProcess("nim", args=["c", "-r", "mytestfile.nim"], options={poUsePath}) let outp_shell = execProcess("nim c -r mytestfile.nim") # Note: outp may have an interleave of text from the nim compile # and any output from mytestfile when it runsИсходный код Изменить proc execProcesses(cmds: openArray[string]; options = {poStdErrToStdOut, poParentStreams}; n = countProcessors(); beforeRunEvent: proc (idx: int) = nil; afterRunEvent: proc (idx: int; p: Process) = nil): int {. ...gcsafe, extern: "nosp$1", raises: [ValueError, OSError, IOError], tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect], effectsOf: [beforeRunEvent, afterRunEvent], ...forbids: [].}-
Выполняет команды
cmdsпараллельно. Создаётnпроцессов, которые выполняются параллельно.Возвращает наибольшее (по модулю) возвращаемое значение всех процессов. Выполняет
Исходный код ИзменитьbeforeRunEventперед запуском каждой команды. proc hasData(p: Process): bool {....raises: [], tags: [], forbids: [].}- Исходный код Изменить
proc inputHandle(p: Process): FileHandle {....gcsafe, raises: [], extern: "nosp$1", tags: [], forbids: [].}- Возвращает дескриптор файла ввода
pдля записи.Предупреждение: ВозвращённыйFileHandleне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Изменить proc inputStream(p: Process): Stream {....gcsafe, extern: "nosp$1", tags: [], raises: [], forbids: [].}- Возвращает поток ввода
pдля записи.Предупреждение: ВозвращённыйStreamне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Изменить proc kill(p: Process) {....gcsafe, extern: "nosp$1", tags: [], raises: [OSError], forbids: [].}-
Завершает процесс
p.На операционных системах Posix процедура отправляет
SIGKILLпроцессу. На Windowskillявляется просто псевдонимом для terminate().См. также:
- процедура suspend
- процедура resume
- процедура terminate
- posix_utils.sendSignal(pid: Pid, signal: int)
proc outputHandle(p: Process): FileHandle {....gcsafe, extern: "nosp$1", raises: [], tags: [], forbids: [].}- Возвращает дескриптор файла вывода
pдля чтения.Предупреждение: ВозвращённыйFileHandleне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Изменить proc outputStream(p: Process): Stream {....gcsafe, extern: "nosp$1", raises: [IOError, OSError], tags: [], forbids: [].}-
Возвращает поток вывода
pдля чтения.Вы не можете выполнять операции peek/write/setOption с этим потоком. Используйте процедуру peekableOutputStream, если вам нужно просмотреть поток.
Предупреждение: ВозвращённыйStreamне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Изменить
proc peekableErrorStream(p: Process): Stream {....gcsafe, extern: "nosp$1", tags: [], raises: [], forbids: [].}-
Возвращает поток ошибок
pдля чтения из него.Вы можете выполнить операцию peek для возвращаемого потока.
Предупреждение: ВозвращаемыйStreamне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Редактировать proc peekableOutputStream(p: Process): Stream {....gcsafe, extern: "nosp$1", tags: [], raises: [], forbids: [].}-
Возвращает поток вывода
pдля чтения из него.Вы можете выполнить операцию peek для возвращаемого потока.
Предупреждение: ВозвращаемыйStreamне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Редактировать proc peekExitCode(p: Process): int {....gcsafe, extern: "nosp$1", raises: [OSError], tags: [], forbids: [].}-
Возвращает
-1, если процесс всё ещё выполняется. В противном случае возвращает код выхода процесса.В системах POSIX, если процесс завершился из-за сигнала, будет возвращено значение 128 + номер сигнала.
Исходный код Редактировать proc processID(p: Process): int {....gcsafe, extern: "nosp$1", raises: [], tags: [], forbids: [].}-
Возвращает идентификатор процесса
p.См. также:
Исходный код Редактировать proc readLines(p: Process): (seq[string], int) {. ...raises: [OSError, IOError, ValueError], tags: [ReadIOEffect, TimeEffect], forbids: [].}-
Удобная функция для работы с
startProcessдля чтения данных из фонового процесса.См. также:
Пример:
const opts = {poUsePath, poDaemon, poStdErrToStdOut} var ps: seq[Process] for prog in ["a", "b"]: # run 2 progs in parallel ps.add startProcess("nim", "", ["r", prog], nil, opts) for p in ps: let (lines, exCode) = p.readLines if exCode != 0: for line in lines: echo line p.closeИсходный код Редактировать proc resume(p: Process) {....gcsafe, extern: "nosp$1", tags: [], raises: [], forbids: [].}-
Возобновляет процесс
p.См. также:
Исходный код Редактировать proc running(p: Process): bool {....gcsafe, extern: "nosp$1", raises: [OSError], tags: [], forbids: [].}- Возвращает true, если процесс
pвсё ещё выполняется. Возвращает результат немедленно. Исходный код Редактировать proc startProcess(command: string; workingDir: string = ""; args: openArray[string] = []; env: StringTableRef = nil; options: set[ProcessOption] = {poStdErrToStdOut}): owned( Process) {....gcsafe, extern: "nosp$1", raises: [OSError, IOError], tags: [ExecIOEffect, ReadEnvEffect, RootEffect], forbids: [].}-
Запускает процесс.
Command— исполняемый файл,workingDir— рабочая директория процесса. ЕслиworkingDir == "", используется текущая директория (по умолчанию).args— аргументы командной строки, передаваемые процессу. Во многих операционных системах первый аргумент командной строки — имя исполняемого файла.argsне должен содержать этот аргумент!env— окружение, которое будет передано процессу. Еслиenv == nil(по умолчанию), окружение наследуется от родительского процесса.options— дополнительные флаги, которые могут быть переданыstartProcess. См. документацию ProcessOption для значения этих флагов.После завершения работы необходимо закрыть процесс.
Обратите внимание, что вы не можете передавать любые
argsесли вы используете опциюpoEvalCommand, которая вызывает оболочку системы для запуска указанногоcommand. В этом случае вы должны вручную конкатенировать содержимоеargsсcommand, тщательно экранируя/цитируя любые специальные символы, так как это будет передано неизменно оболочке системы. Каждая система/оболочка может иметь разные правила экранирования, поэтому постарайтесь избегать такого вызова оболочки, если это возможно, так как это приводит к непереносимому программному обеспечению.Значение возврата: новый созданный объект процесса. Никогда не возвращается Nil, но
OSErrorгенерируется в случае ошибки.См. также:
Исходный код Редактировать proc suspend(p: Process) {....gcsafe, extern: "nosp$1", tags: [], raises: [], forbids: [].}-
Приостанавливает процесс
p.См. также:
Исходный код Редактировать proc terminate(p: Process) {....gcsafe, extern: "nosp$1", tags: [], raises: [OSError], forbids: [].}-
Останавливает процесс
p.В системах POSIX процедура отправляет
SIGTERMпроцессу. В Windows вызывается функция Win32 APITerminateProcess()для остановки процесса.См. также:
Исходный код Редактировать proc waitForExit(p: Process; timeout: int = -1): int {....gcsafe, extern: "nosp$1", raises: [OSError, ValueError], tags: [TimeEffect], forbids: [].}- Ожидает завершения процесса и возвращает код ошибки
p.Предупреждение: Будьте осторожны при использованииwaitForExitдля процессов, созданных безpoParentStreams, поскольку они могут заполнять буферы вывода, вызывая тупик.В системах POSIX, если процесс завершился из-за сигнала, будет возвращено значение 128 + номер сигнала.
Предупреждение: При работе с параметрамиИсходный код Редактироватьtimeoutпомните, что значение обычно выражается в миллисекундах, и убедитесь, что используется правильная единица времени, чтобы избежать неожиданного поведения.
Итераторы
iterator lines(p: Process; keepNewLines = false): string {. ...raises: [OSError, IOError, ValueError], tags: [ReadIOEffect, TimeEffect], forbids: [].}-
Удобный итератор для работы с
startProcessдля чтения данных из фонового процесса.См. также:
Пример:
const opts = {poUsePath, poDaemon, poStdErrToStdOut} var ps: seq[Process] for prog in ["a", "b"]: # run 2 progs in parallel ps.add startProcess("nim", "", ["r", prog], nil, opts) for p in ps: var i = 0 for line in p.lines: echo line i.inc if i > 100: break p.closeИсходный код Редактировать
© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/osproc.html