osproc
Этот модуль реализует расширенные возможности для выполнения процессов ОС и межпроцессного взаимодействия.
См. также:
Импорты
- strutils, os, strtabs, streams, cpuinfo, streamwrapper, since, posix, times
Типы
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. Исходный код Редактировать
Process = ref ProcessObj
- Представляет процесс операционной системы. Исходный код Редактировать
Константы
poDemon = poDaemon
- Версии Nim до 0.20 использовали неправильное написание ("demon"). Теперь
ProcessOptionиспользует правильное написание ("daemon"), и это необходимо только для обратной совместимости. Исходный код Редактировать
Процедуры
proc processID(p: Process): int {...}{.gcsafe, extern: "nosp$1", raises: [], tags: [].}-
Возвращает идентификатор процесса
p.См. также:
Исходный код Изменить proc inputHandle(p: Process): FileHandle {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}-
Возвращает дескриптор файла ввода процесса
pдля записи.ПРЕДУПРЕЖДЕНИЕ: Возвращаемый дескриптор
FileHandleне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Изменить proc outputHandle(p: Process): FileHandle {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}-
Возвращает дескриптор файла вывода процесса
pдля чтения.ПРЕДУПРЕЖДЕНИЕ: Возвращаемый дескриптор
FileHandleне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Изменить proc errorHandle(p: Process): FileHandle {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}-
Возвращает дескриптор файла ошибок процесса
pдля чтения.ПРЕДУПРЕЖДЕНИЕ: Возвращаемый дескриптор
FileHandleне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Изменить proc countProcessors(): int {...}{.gcsafe, extern: "nosp$1", raises: [], tags: [].}- Возвращает количество процессоров/ядер в машине. Возвращает 0, если количество не может быть определено. Реализовано путем вызова
cpuinfo.countProcessors. Исходный код Изменить 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", tags: [ExecIOEffect, TimeEffect, ReadEnvEffect, RootEffect], raises: [Exception, OSError].}-
Выполняет команды
cmdsпараллельно. Создаётnпроцессов, которые выполняются параллельно.Возвращает наибольшее (по модулю) возвращаемое значение всех процессов. Выполняет
Исходный код ИзменитьbeforeRunEventперед выполнением каждой команды. proc readLines(p: Process): (seq[string], int) {...}{. raises: [Exception, IOError, OSError], tags: [ReadIOEffect].}-
Удобная функция для работы с
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 execProcess(command: string; workingDir: string = ""; args: openArray[string] = []; env: StringTableRef = nil; options: set[ProcessOption] = {poStdErrToStdOut, poUsePath, poEvalCommand}): TaintedString {...}{. gcsafe, extern: "nosp$1", tags: [ExecIOEffect, ReadIOEffect, RootEffect], raises: [Exception, IOError, OSError].}-
Удобная процедура, которая выполняет
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 startProcess(command: string; workingDir: string = ""; args: openArray[string] = []; env: StringTableRef = nil; options: set[ProcessOption] = {poStdErrToStdOut}): owned( Process) {...}{.gcsafe, extern: "nosp$1", tags: [ExecIOEffect, ReadEnvEffect, RootEffect], raises: [OSError, Exception].}-
Запускает процесс.
Command- исполняемый файл,workingDir- рабочая директория процесса. ЕслиworkingDir == "", используется текущая директория (по умолчанию).args- аргументы командной строки, передаваемые процессу. На многих операционных системах первый аргумент командной строки - имя исполняемого файла.argsне должен содержать этот аргумент!env- переменные окружения, которые будут переданы процессу. Еслиenv == nil, переменные окружения наследуются от родительского процесса.options- дополнительные флаги, которые могут быть переданыstartProcess. См. документацию ProcessOption для значения этих флагов.Необходимо закрыть процесс после завершения.
Обратите внимание, что вы не можете передать любые
argsесли используете параметрpoEvalCommand, который вызывает оболочку системы для запуска указанногоcommand. В этом случае вам нужно вручную конкатенировать содержимоеargsкcommand, тщательно экранируя/цитируя любые специальные символы, так как это будет передано как есть в оболочку системы. Каждая система/оболочка может иметь различные правила экранирования, поэтому старайтесь избегать этого рода вызова оболочки, если возможно, так как это приводит к непереносимому ПО.Возвращаемое значение: Объект нового процесса. Никогда не возвращается Nil, но
OSErrorгенерируется в случае ошибки.См. также:
Исходный код Изменить proc close(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [WriteIOEffect], raises: [Exception, IOError, OSError].}-
При завершении процесса выполняется очистка связанных дескрипторов.
ПРЕДУПРЕЖДЕНИЕ: Если процесс ещё не завершен, это принудительно завершит процесс. Это может привести к появлению зомби-процессов и утечкам pty.
Исходный код Изменить proc suspend(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].}-
Приостанавливает процесс
p.См. также:
Исходный код Изменить proc resume(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].}-
Возобновляет процесс
p.См. также:
Исходный код Изменить proc running(p: Process): bool {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].}- Возвращает true, если процесс
pвсё ещё запущен. Возвращает результат немедленно. Исходный код Изменить proc terminate(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].}-
Останавливает процесс
p.На системах Posix процедура отправляет
SIGTERMпроцессу. На Windows вызывается функция Win32 APITerminateProcess()для остановки процесса.См. также:
Исходный код Изменить proc kill(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].}-
Завершает процесс
p.На системах Posix процедура отправляет
SIGKILLпроцессу. На Windowskillпросто является алиасом для terminate().См. также:
Исходный код Изменить proc waitForExit(p: Process; timeout: int = -1): int {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError, OSError, ValueError].}-
Ожидает завершения процесса и возвращает код ошибки
p.ПРЕДУПРЕЖДЕНИЕ: Будьте внимательны при использовании
waitForExitдля процессов, созданных безpoParentStreams, потому что они могут заполнять буферы вывода, вызывая тупик.В Posix, если процесс завершился из-за сигнала, возвращается 128 + номер сигнала.
Исходный код Изменить proc peekExitCode(p: Process): int {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}-
Возвращает
-1, если процесс всё ещё запущен. В противном случае - код выхода процесса.В Posix, если процесс завершился из-за сигнала, возвращается 128 + номер сигнала.
Исходный код Изменить proc inputStream(p: Process): Stream {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].}
-
Возвращает входной поток
pдля записи.ПРЕДУПРЕЖДЕНИЕ: Возвращённый
Streamне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Редактировать proc outputStream(p: Process): Stream {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].}-
Возвращает выходной поток
pдля чтения.Вы не можете выполнять операции peek/write/setOption для этого потока. Используйте peekableOutputStream proc, если вам нужно просмотреть поток.
ПРЕДУПРЕЖДЕНИЕ: Возвращённый
Streamне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Редактировать proc errorStream(p: Process): Stream {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].}-
Возвращает поток ошибок
pдля чтения.Вы не можете выполнять операции peek/write/setOption для этого потока. Используйте peekableErrorStream proc, если вам нужно просмотреть поток.
ПРЕДУПРЕЖДЕНИЕ: Возвращённый
Streamне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Редактировать proc peekableOutputStream(p: Process): Stream {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].}-
Возвращает выходной поток
pдля чтения.Можно просмотреть возвращённый поток.
ПРЕДУПРЕЖДЕНИЕ: Возвращённый
Streamне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Редактировать proc peekableErrorStream(p: Process): Stream {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].}-
Возвращает поток ошибок
pдля чтения.Можно выполнить операцию peek для возвращённого потока.
ПРЕДУПРЕЖДЕНИЕ: Возвращённый
Streamне следует закрывать вручную, так как он закрывается при закрытии процессаp.См. также:
Исходный код Редактировать proc execCmd(command: string): int {...}{.gcsafe, extern: "nosp$1", tags: [ ExecIOEffect, ReadIOEffect, RootEffect], raises: [].}-
Выполняет
commandи возвращает его код ошибки.Стандартные входные, выходные и потоки ошибок наследуются от вызывающего процесса. Эта операция также часто называется система.
См. также:
Пример:
let errC = execCmd("nim c -r mytestfile.nim")Исходный код Редактировать proc hasData(p: Process): bool {...}{.raises: [], tags: [].}- Исходный код Редактировать
proc execCmdEx(command: string; options: set[ProcessOption] = {poStdErrToStdOut, poUsePath}; env: StringTableRef = nil; workingDir = ""; input = ""): tuple[ output: TaintedString, exitCode: int] {...}{. tags: [ExecIOEffect, ReadIOEffect, RootEffect], gcsafe, raises: [OSError, Exception, IOError].}-
Удобная процедура, которая выполняет
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 strutils, strtabs stripLineEnd(result[0]) ## portable way to remove trailing newline, if any doAssert result == ("12", 0) doAssert execCmdEx("ls --nonexistant").exitCode != 0 when defined(posix): assert execCmdEx("echo $FO", env = newStringTable({"FO": "B"})) == ("B\n", 0) assert execCmdEx("echo $PWD", workingDir = "/") == ("/\n", 0)Исходный код Редактировать
Итераторы
iterator lines(p: Process): string {...}{.tags: [ReadIOEffect], raises: [Exception, IOError, OSError].}-
Удобный итератор для работы с
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Исходный код Редактировать
Экспорт
- quoteShell, quoteShellWindows, quoteShellPosix
© 2006–2021 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/osproc.html