This module implements an advanced facility for executing OS processes and process communication.
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. poDemon ## Windows: The program creates no Window. ## Unix: Start the program as a demon. This is still ## work in progress!
Process = ref ProcessObj
poUseShell = poUsePath
proc startCmd(command: string; options: set[ProcessOption] = {poStdErrToStdOut, poUsePath}): Process {...}{. tags: [ExecIOEffect, ReadEnvEffect, RootEffect], deprecated, raises: [Exception].}
proc processID(p: Process): int {...}{.gcsafe, extern: "nosp$1", raises: [], tags: [].}
proc inputHandle(p: Process): FileHandle {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}
returns p
's input file handle for writing to.
Warning: The returned FileHandle should not be closed manually as it is closed when closing the Process p
.
proc outputHandle(p: Process): FileHandle {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}
returns p
's output file handle for reading from.
Warning: The returned FileHandle should not be closed manually as it is closed when closing the Process p
.
proc errorHandle(p: Process): FileHandle {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}
returns p
's error file handle for reading from.
Warning: The returned FileHandle should not be closed manually as it is closed when closing the Process p
.
proc countProcessors(): int {...}{.gcsafe, extern: "nosp$1", raises: [], tags: [].}
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].}
proc execProcess(command: string; args: openArray[string] = []; env: StringTableRef = nil; options: set[ProcessOption] = { poStdErrToStdOut, poUsePath, poEvalCommand}): TaintedString {...}{.gcsafe, extern: "nosp$1", tags: [ExecIOEffect, ReadIOEffect, RootEffect], raises: [Exception].}
command
with startProcess
and returns its output as a string. WARNING: this function uses poEvalCommand by default for backward compatibility. Make sure to pass options explicitly.let outp = 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}): Process {...}{.gcsafe, extern: "nosp$1", tags: [ExecIOEffect, ReadEnvEffect, RootEffect], raises: [OSError, Exception, ValueError].}
Starts a process. Command is the executable file, workingDir is the process's working directory. If workingDir == ""
the current directory is used. args are 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. args should not contain this argument! env is the environment that will be passed to the process. If env == nil
the environment is inherited of the parent process. options are additional flags that may be passed to startProcess. 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 args if you use the option poEvalCommand
, which invokes the system shell to run the specified command. In this situation you have to concatenate manually the contents of args to command carefully 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 EOS
is raised in case of an error.
proc close(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}
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.
proc suspend(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}
proc resume(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}
proc running(p: Process): bool {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}
proc terminate(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}
SIGTERM
to the process. On Windows the Win32 API function TerminateProcess()
is called to stop the process. proc kill(p: Process) {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}
SIGKILL
to the process. On Windows kill()
is simply an alias for terminate()
. proc waitForExit(p: Process; timeout: int = -1): int {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}
waits for the process to finish and returns p's error code.
Warning: Be careful when using waitForExit for processes created without poParentStreams because they may fill output buffers, causing deadlock.
On posix, if the process has exited because of a signal, 128 + signal number will be returned.
proc peekExitCode(p: Process): int {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}
return -1 if 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.
proc inputStream(p: Process): Stream {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}
returns p
's input stream for writing to.
Warning: The returned Stream should not be closed manually as it is closed when closing the Process p
.
proc outputStream(p: Process): Stream {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}
returns p
's output stream for reading from.
Warning: The returned Stream should not be closed manually as it is closed when closing the Process p
.
proc errorStream(p: Process): Stream {...}{.gcsafe, extern: "nosp$1", tags: [], raises: [].}
returns p
's error stream for reading from.
Warning: The returned Stream should not be closed manually as it is closed when closing the Process p
.
proc execCmd(command: string): int {...}{.gcsafe, extern: "nosp$1", tags: [ExecIOEffect, ReadIOEffect, RootEffect], raises: [OSError].}
command
and returns its error code. Standard input, output, error streams are inherited from the calling process. This operation is also often called system.let errC = execCmd("nim c -r mytestfile.nim")
proc select(readfds: var seq[Process]; timeout = 500): int {...}{.gcsafe, locks: 0, deprecated, raises: [OSError], tags: [].}
select with a sensible Nim interface. timeout is in milliseconds. Specify -1 for no timeout. Returns the number of processes that are ready to read from. The processes that are ready to be read from are removed from readfds.
Warning: This function may give unexpected or completely wrong results on Windows.
Deprecated since version 0.17.0: This procedure isn't cross-platform and so should not be used in newly written code.
proc hasData(p: Process): bool {...}{.raises: [], tags: [].}
y < x
. proc execCmdEx(command: string; options: set[ProcessOption] = {poStdErrToStdOut, poUsePath}): tuple[ output: TaintedString, exitCode: int] {...}{.tags: [ExecIOEffect, ReadIOEffect, RootEffect], gcsafe, raises: [OSError, Exception, ValueError].}
let (outp, errC) = execCmdEx("nim c -r mytestfile.nim")
© 2006–2018 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/osproc.html