Functions for starting and interacting with other processes, and for working with the current process' execution environment.
Runs program directly | Runs shell command | |
---|---|---|
Low-level process creation | spawnProcess | spawnShell |
Automatic input/output redirection using pipes | pipeProcess | pipeShell |
Execute and wait for completion, collect output | execute | executeShell |
Spawns a new process, optionally assigning it an arbitrary set of standard input, output, and error streams.
The function returns immediately, leaving the child process to execute in parallel with its parent. It is recommended to always call wait on the returned Pid, as detailed in the documentation for wait.
// Run an executable called "prog" located in the current working // directory: auto pid = spawnProcess("./prog"); scope(exit) wait(pid); // We can do something else while the program runs. The scope guard // ensures that the process is waited for at the end of the scope. ... // Run DMD on the file "myprog.d", specifying a few compiler switches: auto dmdPid = spawnProcess(["dmd", "-O", "-release", "-inline", "myprog.d" ]); if (wait(dmdPid) != 0) writeln("Compilation failed!");
wait(spawnProcess("myapp", ["foo" : "bar"], Config.newEnv));
// Run DMD on the file myprog.d, logging any error messages to a // file named errors.log. auto logFile = File("errors.log", "w"); auto pid = spawnProcess(["dmd", "myprog.d"], std.stdio.stdin, std.stdio.stdout, logFile); if (wait(pid) != 0) writeln("Compilation failed. See errors.log for details.");
char[][] args | An array which contains the program name as the zeroth element and any command-line arguments in the following elements. |
File stdin | The standard input stream of the child process. This can be any std.stdio.File that is opened for reading. By default the child process inherits the parent's input stream. |
File stdout | The standard output stream of the child process. This can be any std.stdio.File that is opened for writing. By default the child process inherits the parent's output stream. |
File stderr | The standard error stream of the child process. This can be any std.stdio.File that is opened for writing. By default the child process inherits the parent's error stream. |
string[string] env | Additional environment variables for the child process. |
Config config | Flags that control process creation. See Config for an overview of available flags. |
A variation on spawnProcess that runs the given command through the current user's preferred command interpreter (aka. shell).
The string command is passed verbatim to the shell, and is therefore
subject to its rules about command structure, argument/filename quoting
and escaping of special characters.
The path to the shell executable is determined by the userShell
function.
In all other respects this function works just like spawnProcess.
Please refer to the spawnProcess documentation for descriptions
of the other function parameters, the return value and any exceptions
that may be thrown.
// Run the command/program "foo" on the file named "my file.txt", and // redirect its output into foo.log. auto pid = spawnShell(`foo "my file.txt" > foo.log`); wait(pid);
Flags that control the behaviour of spawnProcess and spawnShell.
Use bitwise OR to combine flags.
auto logFile = File("myapp_error.log", "w"); // Start program, suppressing the console window (Windows only), // redirect its error stream to logFile, and leave logFile open // in the parent process as well. auto pid = spawnProcess("myapp", stdin, stdout, logFile, Config.retainStderr | Config.suppressConsole); scope(exit) { auto exitCode = wait(pid); logFile.writeln("myapp exited with code ", exitCode); logFile.close(); }
By default, the child process inherits the parent's environment, and any environment variables passed to spawnProcess will be added to it. If this flag is set, the only variables in the child process' environment will be those given to spawnProcess.
Unless the child process inherits the standard input/output/error streams of its parent, one almost always wants the streams closed in the parent when spawnProcess returns. Therefore, by default, this is done. If this is not desirable, pass any of these options to spawnProcess.
On Windows, if the child process is a console application, this flag will prevent the creation of a console window. Otherwise, it will be ignored. On POSIX, suppressConsole has no effect.
On POSIX, open file descriptors are by default inherited by the child process. As this may lead to subtle bugs when pipes or multiple threads are involved, spawnProcess ensures that all file descriptors except the ones that correspond to standard input/output/error are closed in the child process when it starts. Use inheritFDs to prevent this.
On Windows, this option has no effect, and any handles which have been explicitly marked as inheritable will always be inherited by the child process.
A handle that corresponds to a spawned process.
An operating system handle to the process.
This handle is used to specify the process in OS-specific APIs.
On POSIX, this function returns a core.sys.posix.sys.types.pid_t
with the same value as Pid.processID, while on Windows it returns
a core.sys.windows.windows.HANDLE.
Once wait has been called on the Pid, this method
will return an invalid handle.
Waits for the process associated with pid to terminate, and returns its exit status.
In general one should always wait for child processes to terminate
before exiting the parent process. Otherwise, they may become
"zombies" – processes
that are defunct, yet still occupy a slot in the OS process table.
If the process has already terminated, this function returns directly.
The exit code is cached, so that if wait() is called multiple times on
the same Pid it will always return the same value.
A non-blocking version of wait.
If the process associated with pid has already terminated,
tryWait has the exact same effect as wait.
In this case, it returns a struct where the terminated field
is set to true and the status field has the same
interpretation as the return value of wait.
If the process has not yet terminated, this function differs
from wait in that does not wait for this to happen, but instead
returns immediately. The terminated field of the returned
tuple will then be set to false, while the status field
will always be 0 (zero). wait or tryWait should then be
called again on the same Pid at some later time; not only to
get the exit code, but also to avoid the process becoming a "zombie"
when it finally terminates. (See wait for details).
auto pid = spawnProcess("dmd myapp.d"); scope(exit) wait(pid); ... auto dmd = tryWait(pid); if (dmd.terminated) { if (dmd.status == 0) writeln("Compilation succeeded!"); else writeln("Compilation failed"); } else writeln("Still compiling..."); ...Note that in this example, the first wait call will have no effect if the process has already terminated by the time tryWait is called. In the opposite case, however, the scope statement ensures that we always wait for the process if it hasn't terminated by the time we reach the end of the scope.
Attempts to terminate the process associated with pid.
The effect of this function, as well as the meaning of codeOrSignal,
is highly platform dependent. Details are given below. Common to all
platforms is that this function only initiates termination of the process,
and returns immediately. It does not wait for the process to end,
nor does it guarantee that the process does in fact get terminated.
Always call wait to wait for a process to complete, even if kill
has been called on it.
auto pid = spawnProcess("some_app"); kill(pid, 10); assert (wait(pid) == 10);
import core.sys.posix.signal: SIGKILL; auto pid = spawnProcess("some_app"); kill(pid, SIGKILL); assert (wait(pid) == -SIGKILL); // Negative return value on POSIX!
Creates a unidirectional pipe.
Data is written to one end of the pipe and read from the other.
auto p = pipe(); p.writeEnd.writeln("Hello World"); assert (p.readEnd.readln().chomp() == "Hello World");Pipes can, for example, be used for interprocess communication by spawning a new process and passing one end of the pipe to the child, while the parent uses the other end. (See also pipeProcess and pipeShell for an easier way of doing this.)
// Use cURL to download the dlang.org front page, pipe its // output to grep to extract a list of links to ZIP files, // and write the list to the file "D downloads.txt": auto p = pipe(); auto outFile = File("D downloads.txt", "w"); auto cpid = spawnProcess(["curl", "http://dlang.org/download.html"], std.stdio.stdin, p.writeEnd); scope(exit) wait(cpid); auto gpid = spawnProcess(["grep", "-o", `http://\S*\.zip`], p.readEnd, outFile); scope(exit) wait(gpid);
An interface to a pipe created by the pipe function.
The read end of the pipe.
The write end of the pipe.
Closes both ends of the pipe.
Normally it is not necessary to do this manually, as std.stdio.File
objects are automatically closed when there are no more references
to them.
Note that if either end of the pipe has been passed to a child process,
it will only be closed in the parent process. (What happens in the
child process is platform dependent.)
Starts a new process, creating pipes to redirect its standard input, output and/or error streams.
pipeProcess and pipeShell are convenient wrappers around
spawnProcess and spawnShell, respectively, and
automate the task of redirecting one or more of the child process'
standard streams through pipes. Like the functions they wrap,
these functions return immediately, leaving the child process to
execute in parallel with the invoking process. It is recommended
to always call wait on the returned ProcessPipes.pid,
as detailed in the documentation for wait.
The args/program/command, env and config
parameters are forwarded straight to the underlying spawn functions,
and we refer to their documentation for details.
char[][] args | An array which contains the program name as the zeroth element and any command-line arguments in the following elements. (See spawnProcess for details.) |
program | The program name, without command-line arguments. (See spawnProcess for details.) |
command | A shell command which is passed verbatim to the command interpreter. (See spawnShell for details.) |
Redirect redirect | Flags that determine which streams are redirected, and how. See Redirect for an overview of available flags. |
string[string] env | Additional environment variables for the child process. (See spawnProcess for details.) |
Config config | Flags that control process creation. See Config for an overview of available flags, and note that the retainStd... flags have no effect in this function. |
auto pipes = pipeProcess("my_application", Redirect.stdout | Redirect.stderr); scope(exit) wait(pipes.pid); // Store lines of output. string[] output; foreach (line; pipes.stdout.byLine) output ~= line.idup; // Store lines of errors. string[] errors; foreach (line; pipes.stderr.byLine) errors ~= line.idup;
Flags that can be passed to pipeProcess and pipeShell to specify which of the child process' standard streams are redirected. Use bitwise OR to combine flags.
Redirect the standard input, output or error streams, respectively.
Redirect all three streams. This is equivalent to Redirect.stdin | Redirect.stdout | Redirect.stderr.
Redirect the standard error stream into the standard output stream. This can not be combined with Redirect.stderr.
Redirect the standard output stream into the standard error stream. This can not be combined with Redirect.stdout.
Object which contains std.stdio.File handles that allow communication with a child process through its standard streams.
The Pid of the child process.
An std.stdio.File that allows writing to the child process' standard input stream.
An std.stdio.File that allows reading from the child process' standard output stream.
An std.stdio.File that allows reading from the child process' standard error stream.
Executes the given program or shell command and returns its exit code and output.
execute and executeShell start a new process using spawnProcess and spawnShell, respectively, and wait for the process to complete before returning. The functions capture what the child process prints to both its standard output and standard error streams, and return this together with its exit code.
auto dmd = execute("dmd", "myapp.d"); if (dmd.status != 0) writeln("Compilation failed:\n", dmd.output); auto ls = executeShell("ls -l"); if (ls.status == 0) writeln("Failed to retrieve file listing"); else writeln(ls.output);
char[][] args | An array which contains the program name as the zeroth element and any command-line arguments in the following elements. (See spawnProcess for details.) |
program | The program name, without command-line arguments. (See spawnProcess for details.) |
command | A shell command which is passed verbatim to the command interpreter. (See spawnShell for details.) |
string[string] env | Additional environment variables for the child process. (See spawnProcess for details.) |
Config config | Flags that control process creation. See Config for an overview of available flags, and note that the retainStd... flags have no effect in this function. |
size_t maxOutput | The maximum number of bytes of output that should be captured. |
An exception that signals a problem with starting or waiting for a process.
Determines the path to the current user's default command interpreter.
On Windows, this function returns the contents of the COMSPEC environment
variable, if it exists. Otherwise, it returns the string "cmd.exe".
On POSIX, userShell returns the contents of the SHELL environment
variable, if it exists and is non-empty. Otherwise, it returns
"/bin/sh".
Returns the process ID number of the current process.
Escapes an argv-style argument array to be used with spawnShell, pipeShell or executeShell.
string url = "http://dlang.org/"; executeShell(escapeShellCommand("wget", url, "-O", "dlang-index.html"));
Concatenate multiple escapeShellCommand and escapeShellFileName results to use shell redirection or piping operators.
executeShell( escapeShellCommand("curl", "http://dlang.org/download.html") ~ "|" ~ escapeShellCommand("grep", "-o", `http://\S*\.zip`) ~ ">" ~ escapeShellFileName("D download links.txt"));
Quotes a command-line argument in a manner conforming to the behavior of CommandLineToArgvW.
Escapes a filename to be used for shell redirection with spawnShell, pipeShell or executeShell.
Manipulates environment variables using an associative-array-like interface.
This class contains only static methods, and cannot be instantiated. See below for examples of use.
Retrieves the value of the environment variable with the given name.
auto path = environment["PATH"];
Retrieves the value of the environment variable with the given name, or a default value if the variable doesn't exist.
Unlike environment.opIndex, this function never throws.
auto sh = environment.get("SHELL", "/bin/sh");This function is also useful in checking for the existence of an environment variable.
auto myVar = environment.get("MYVAR"); if (myVar is null) { // Environment variable doesn't exist. // Note that we have to use 'is' for the comparison, since // myVar == null is also true if the variable exists but is // empty. }
Assigns the given value to the environment variable with the given name.
If the variable does not exist, it will be created. If it already exists, it will be overwritten.
environment["foo"] = "bar";
Removes the environment variable with the given name.
If the variable isn't in the environment, this function returns successfully without doing anything.
Copies all environment variables into an associative array.
Execute command in a command shell.
This function is scheduled for deprecation. Please use spawnShell or executeShell instead.
Replace the current process by executing a command, pathname, with the arguments in argv.
These functions are scheduled for deprecation. Please use
spawnShell instead (or, alternatively, the homonymous C
functions declared in std.c.process.)
Typically, the first element of argv is
the command being executed, i.e. argv[0] == pathname. The 'p'
versions of exec search the PATH environment variable for pathname. The 'e' versions additionally take the new process'
environment variables as an array of strings of the form key=value.
Does not return on success (the current process will have been
replaced). Returns -1 on failure with no indication of the
underlying error.
Returns the process ID of the calling process, which is guaranteed to be unique on the system. This call is always successful.
This function is scheduled for deprecation. Please use thisProcessID instead.
writefln("Current process id: %s", getpid());
Runs cmd in a shell and returns its standard output. If the process could not be started or exits with an error code, throws ErrnoException.
This function is scheduled for deprecation. Please use executeShell instead.
auto tempFilename = chomp(shell("mcookie")); auto f = enforce(fopen(tempFilename), "w"); scope(exit) { fclose(f) == 0 || assert(false); system(escapeShellCommand("rm", tempFilename)); } ... use f ...
Gets the value of environment variable name as a string. Calls std.c.stdlib.getenv internally.
This function is scheduled for deprecation. Please use environment.get instead.