On this page
osproc
This module implements an advanced facility for executing OS processes and process communication.
See also:
Imports
Types
-
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! - Options that can be passed to startProcess proc. Source Edit
-
Process = ref ProcessObj - Represents an operating system process. Source Edit
Consts
-
poDemon = poDaemon -
Nim versions before 0.20 used the wrong spelling ("demon"). Now
ProcessOptionuses the correct spelling ("daemon"), and this is needed just for backward compatibility. Source Edit
Procs
-
proc processID(p: Process): int {...}{.gcsafe, extern: "nosp$1", raises: [], tags: [].} -
Returns
p's process ID.See also:
Source Edit -
proc inputHandle(p: Process): FileHandle {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].} -
Returns
p's input file handle for writing to.WARNING: The returned
FileHandleshould not be closed manually as it is closed when closing the Processp.See also:
Source Edit -
proc outputHandle(p: Process): FileHandle {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].} -
Returns
p's output file handle for reading from.WARNING: The returned
FileHandleshould not be closed manually as it is closed when closing the Processp.See also:
Source Edit -
proc errorHandle(p: Process): FileHandle {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].} -
Returns
p's error file handle for reading from.WARNING: The returned
FileHandleshould not be closed manually as it is closed when closing the Processp.See also:
Source Edit -
proc countProcessors(): int {...}{.gcsafe, extern: "nosp$1", raises: [], tags: [].} -
Returns the number of the processors/cores the machine has. Returns 0 if it cannot be detected. It is implemented just calling
cpuinfo.countProcessors. Source Edit -
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].} -
Executes the commands
cmdsin parallel. Createsnprocesses that execute in parallel.The highest (absolute) return value of all processes is returned. Runs
Source EditbeforeRunEventbefore running each command. -
proc readLines(p: Process): (seq[string], int) {...}{. raises: [Exception, IOError, OSError], tags: [ReadIOEffect].} -
Convenience function for working with
startProcessto read data from a background process.See also:
Example:
Source Editconst 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].} -
A convenience procedure that executes
commandwithstartProcessand returns its output as a string.WARNING: This function uses
poEvalCommandby default for backwards compatibility. Make sure to pass options explicitly.See also:
Example:
Source Editlet 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].} -
Starts a process.
Commandis the executable file,workingDiris the process's working directory. IfworkingDir == ""the current directory is used (default).argsare the command line arguments that are passed to the process. On many operating systems, the first command line argument is the name of the executable.argsshould not contain this argument!envis the environment that will be passed to the process. Ifenv == nil(default) the environment is inherited of the parent process.optionsare additional flags that may be passed tostartProcess. See the documentation of ProcessOption for the meaning of these flags.You need to close the process when done.
Note that you can't pass any
argsif you use the optionpoEvalCommand, which invokes the system shell to run the specifiedcommand. In this situation you have to concatenate manually the contents ofargstocommandcarefully escaping/quoting any special characters, since it will be passed as is to the system shell. Each system/shell may feature different escaping rules, so try to avoid this kind of shell invocation if possible as it leads to non portable software.Return value: The newly created process object. Nil is never returned, but
OSErroris raised in case of an error.See also:
Source Edit -
proc close(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [WriteIOEffect], raises: [Exception, IOError, OSError].} -
When the process has finished executing, cleanup related handles.
WARNING: If the process has not finished executing, this will forcibly terminate the process. Doing so may result in zombie processes and pty leaks.
Source Edit -
proc suspend(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].} -
Suspends the process
p.See also:
Source Edit -
proc resume(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].} -
Resumes the process
p.See also:
Source Edit -
proc running(p: Process): bool {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].} -
Returns true if the process
pis still running. Returns immediately. Source Edit -
proc terminate(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].} -
Stop the process
p.On Posix OSes the procedure sends
SIGTERMto the process. On Windows the Win32 API functionTerminateProcess()is called to stop the process.See also:
Source Edit -
proc kill(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].} -
Kill the process
p.On Posix OSes the procedure sends
SIGKILLto the process. On Windowskillis simply an alias for terminate().See also:
Source Edit -
proc waitForExit(p: Process; timeout: int = -1): int {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError, OSError, ValueError].} -
Waits for the process to finish and returns
p's error code.WARNING: Be careful when using
waitForExitfor processes created withoutpoParentStreamsbecause they may fill output buffers, causing deadlock.On posix, if the process has exited because of a signal, 128 + signal number will be returned.
Source Edit -
proc peekExitCode(p: Process): int {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].} -
Return
-1if the process is still running. Otherwise the process' exit code.On posix, if the process has exited because of a signal, 128 + signal number will be returned.
Source Edit -
proc inputStream(p: Process): Stream {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].} -
Returns
p's input stream for writing to.WARNING: The returned
Streamshould not be closed manually as it is closed when closing the Processp.See also:
Source Edit -
proc outputStream(p: Process): Stream {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].} -
Returns
p's output stream for reading from.You cannot perform peek/write/setOption operations to this stream. Use peekableOutputStream proc if you need to peek stream.
WARNING: The returned
Streamshould not be closed manually as it is closed when closing the Processp.See also:
Source Edit -
proc errorStream(p: Process): Stream {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].} -
Returns
p's error stream for reading from.You cannot perform peek/write/setOption operations to this stream. Use peekableErrorStream proc if you need to peek stream.
WARNING: The returned
Streamshould not be closed manually as it is closed when closing the Processp.See also:
Source Edit -
proc peekableOutputStream(p: Process): Stream {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].} -
Returns
p's output stream for reading from.You can peek returned stream.
WARNING: The returned
Streamshould not be closed manually as it is closed when closing the Processp.See also:
Source Edit -
proc peekableErrorStream(p: Process): Stream {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [OSError].} -
Returns
p's error stream for reading from.You can run peek operation to returned stream.
WARNING: The returned
Streamshould not be closed manually as it is closed when closing the Processp.See also:
Source Edit -
proc execCmd(command: string): int {...}{.gcsafe, extern: "nosp$1", tags: [ ExecIOEffect, ReadIOEffect, RootEffect], raises: [].} -
Executes
commandand returns its error code.Standard input, output, error streams are inherited from the calling process. This operation is also often called system.
See also:
Example:
Source Editlet errC = execCmd("nim c -r mytestfile.nim") -
proc hasData(p: Process): bool {...}{.raises: [], tags: [].} - Source Edit
-
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].} -
A convenience proc that runs the
command, and returns itsoutputandexitCode.envandworkingDirparams behave as forstartProcess. Ifinput.len > 0, it is passed as stdin.Note: this could block if
input.lenis greater than your OS's maximum pipe buffer size.See also:
Example:
Source Editvar 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)
Iterators
-
iterator lines(p: Process): string {...}{.tags: [ReadIOEffect], raises: [Exception, IOError, OSError].} -
Convenience iterator for working with
startProcessto read data from a background process.See also:
Example:
Source Editconst 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
Exports
© 2006–2021 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/osproc.html