class

Process

Inherits Reference / Object

Constants

PATH_DELIMITER = ':'

Constructors

new(command : String, args : Enumerable(String) | Nil = nil, env : Env = nil, clear_env : Bool = false, shell : Bool = false, input : Stdio = Redirect::Close, output : Stdio = Redirect::Close, error : Stdio = Redirect::Close, chdir : Path | String | Nil = nil)

Creates and executes a child process.

This starts a new process for command.

shell: false (the default)

command is either a path to the executable to run, or the name of an executable which is then looked up by the operating system. The lookup uses the PATH variable of the current process environment (i.e. ENV["PATH"]). In order to resolve to a specific executable, provide a path instead of only a command name. Process.find_executablecan help with looking up a command in a customPATH`.

The arguments in args are passed as arguments to the child process.

Raises IO::Error if executing command fails, for example because the executable doesn't exist or is not executable.

shell: true

command is a shell script executed in the system shell (/bin/sh on Unix systems, cmd.exe on Windows). Command names are looked up by the shell itself, using the PATH variable of the shell process (i.e. env["PATH"]).

args is unsupported on Windows. On Unix it's passed as additional arguments to the shell process and can be used in the shell script with "${@}" to safely insert them there. If the script is a single command (no whitespace), "${@}" is appended implicitly.

The returned instance represents the shell process, not the process executed for command.

If executing command fails, for example because the executable doesn't exist or is not executable, it may raise IO::Error (on Windows) or return an unsuccessful exit status (on Unix).

Shared parameters

env provides a mapping of environment variables for the child process. If clear_env is true, only these explicit variables are used; if false, the child inherits the parent's environment with env merged.

input, output, error configure the child process's standard streams.

  • Redirect::Close passes the null device
  • Redirect::Pipe creates a pipe that's accessible via #input, #output or #error.
  • Redirect::Inherit to share the parent's streams (STDIN, STDOUT, STDERR).
  • An IO instance creates a pipe that reads/writes into the given IO.

chdir changes the working directory of the child process. If nil, uses the current working directory of the parent process.

Example:

process = Process.new("echo", ["Hello"], output: Process::Redirect::Pipe)
process.output.gets_to_end # => "Hello\n"
process.wait               # => Process::Status[0]

Similar methods:

  • Process.run is a convenient short cut if you just want to run a command and wait for it to finish.
  • Process.exec replaces the current process.
Source
new(process_info : Crystal::System::Process)

:nodoc

Source
new(args : Enumerable(String), *, env : Env = nil, clear_env : Bool = false, input : Stdio = Redirect::Close, output : Stdio = Redirect::Close, error : Stdio = Redirect::Close, chdir : Path | String | Nil = nil) : self

Creates and executes a child process.

This starts a new process for the command given in args[0].

The command is either a path to the executable to run, or the name of an executable which is then looked up by the operating system. The lookup uses the PATH variable of the current process environment (i.e. ENV["PATH"]). In order to resolve to a specific executable, provide a path instead of only a command name. Process.find_executablecan help with looking up a command in a customPATH`.

The following arguments in args are passed as arguments to the child process.

Raises IO::Error if executing args[0] fails, for example because the executable doesn't exist or is not executable.

env provides a mapping of environment variables for the child process. If clear_env is true, only these explicit variables are used; if false, the child inherits the parent's environment with env merged.

input, output, error configure the child process's standard streams.

  • Redirect::Close passes the null device
  • Redirect::Pipe creates a pipe that's accessible via #input, #output or #error.
  • Redirect::Inherit to share the parent's streams (STDIN, STDOUT, STDERR).
  • An IO instance creates a pipe that reads/writes into the given IO.

chdir changes the working directory of the child process. If nil, uses the current working directory of the parent process.

Example:

process = Process.new(["echo", "Hello"], output: Process::Redirect::Pipe)
process.output.gets_to_end # => "Hello\n"
process.wait               # => Process::Status[0]

Similar methods:

  • Process.run is a convenient short cut if you just want to run a command and wait for it to finish.
  • Process.exec replaces the current process.
Source
new(*args : String, env : Env = nil, clear_env : Bool = false, input : Stdio = Redirect::Close, output : Stdio = Redirect::Close, error : Stdio = Redirect::Close, chdir : Path | String | Nil = nil) : self

Creates and executes a child process.

This starts a new process for the command given in args[0].

The command is either a path to the executable to run, or the name of an executable which is then looked up by the operating system. The lookup uses the PATH variable of the current process environment (i.e. ENV["PATH"]). In order to resolve to a specific executable, provide a path instead of only a command name. Process.find_executablecan help with looking up a command in a customPATH`.

The following arguments in args are passed as arguments to the child process.

Raises IO::Error if executing args[0] fails, for example because the executable doesn't exist or is not executable.

env provides a mapping of environment variables for the child process. If clear_env is true, only these explicit variables are used; if false, the child inherits the parent's environment with env merged.

input, output, error configure the child process's standard streams.

  • Redirect::Close passes the null device
  • Redirect::Pipe creates a pipe that's accessible via #input, #output or #error.
  • Redirect::Inherit to share the parent's streams (STDIN, STDOUT, STDERR).
  • An IO instance creates a pipe that reads/writes into the given IO.

chdir changes the working directory of the child process. If nil, uses the current working directory of the parent process.

Example:

process = Process.new(["echo", "Hello"], output: Process::Redirect::Pipe)
process.output.gets_to_end # => "Hello\n"
process.wait               # => Process::Status[0]

Similar methods:

  • Process.run is a convenient short cut if you just want to run a command and wait for it to finish.
  • Process.exec replaces the current process.
Source

Class methods

capture(args : Enumerable(String), *, env : Env | Nil = nil, clear_env : Bool = false, input : Stdio = Redirect::Close, error : Stdio = Redirect::Pipe, chdir : Path | String | Nil = nil) : String

Executes a process and returns its captured standard output.

Raises IO::Error if the process fails to execute or Process::ExitError if does not terminate with a zero exit status.

If error is Redirect::Pipe (default), this method captures the standard error and includes it in the raised Process::ExitError.

Process.capture(%w[echo foo]) # => "foo\n"
Process.capture(%w[nonexist]) # raises Process::ExitError
Source
capture(*args : String, env : Env | Nil = nil, clear_env : Bool = false, input : Stdio = Redirect::Close, error : Stdio = Redirect::Pipe, chdir : Path | String | Nil = nil) : String

Executes a process and returns its captured standard output.

Raises IO::Error if the process fails to execute or Process::ExitError if does not terminate with a zero exit status.

If error is Redirect::Pipe (default), this method captures the standard error and includes it in the raised Process::ExitError.

Process.capture(%w[echo foo]) # => "foo\n"
Process.capture(%w[nonexist]) # raises Process::ExitError
Source
capture?(args : Enumerable(String), *, env : Env | Nil = nil, clear_env : Bool = false, input : Stdio = Redirect::Close, error : Stdio = Redirect::Close, chdir : Path | String | Nil = nil) : String | Nil

Executes a process and returns its captured standard output or nil on failure.

Raises IO::Error if the process fails to execute. Returns nil if the process does not terminate with a zero exit status.

The error stream is not captured by default, but it can be redirected into an IO. Redirect::Pipe creates a pipe, but it cannot be accessed.

Process.capture(%w[echo foo]) # => "foo\n"
Process.capture(%w[nonexist]) # => nil
Source
capture?(*args : String, env : Env | Nil = nil, clear_env : Bool = false, input : Stdio = Redirect::Close, error : Stdio = Redirect::Close, chdir : Path | String | Nil = nil) : String | Nil

Executes a process and returns its captured standard output or nil on failure.

Raises IO::Error if the process fails to execute. Returns nil if the process does not terminate with a zero exit status.

The error stream is not captured by default, but it can be redirected into an IO. Redirect::Pipe creates a pipe, but it cannot be accessed.

Process.capture(%w[echo foo]) # => "foo\n"
Process.capture(%w[nonexist]) # => nil
Source
capture_result(args : Enumerable(String), *, env : Env | Nil = nil, clear_env : Bool = false, input : Stdio = Redirect::Close, output : Stdio = Redirect::Pipe, error : Stdio = Redirect::Pipe, chdir : Path | String | Nil = nil) : Result

Executes a process and returns its result.

Raises IO::Error if the process fails to execute.

If error or output are Redirect::Pipe (default), this method captures the respective standard stream and returns it in the result.

Process.capture_result(%w[echo foo]).output # => "foo\n"
Process.capture_result(%w[nonexist])        # raises Process::ExitError
Source
capture_result(*args : String, env : Env | Nil = nil, clear_env : Bool = false, input : Stdio = Redirect::Close, output : Stdio = Redirect::Pipe, error : Stdio = Redirect::Pipe, chdir : Path | String | Nil = nil) : Result

Executes a process and returns its result.

Raises IO::Error if the process fails to execute.

If error or output are Redirect::Pipe (default), this method captures the respective standard stream and returns it in the result.

Process.capture_result(%w[echo foo]).output # => "foo\n"
Process.capture_result(%w[nonexist])        # raises Process::ExitError
Source
capture_result?(args : Enumerable(String), *, env : Env | Nil = nil, clear_env : Bool = false, input : Stdio = Redirect::Close, output : Stdio = Redirect::Pipe, error : Stdio = Redirect::Pipe, chdir : Path | String | Nil = nil) : Result | Nil

Executes a process and returns its result.

Returns nil if the process fails to execute.

If error or output are Redirect::Pipe (default), this method captures the respective standard stream and returns it in the result.

Process.capture_result?(%w[echo foo]).try(&.output) # => "foo\n"
Process.capture_result?(%w[nonexist])               # => nil
Source
capture_result?(*args : String, env : Env | Nil = nil, clear_env : Bool = false, input : Stdio = Redirect::Close, output : Stdio = Redirect::Pipe, error : Stdio = Redirect::Pipe, chdir : Path | String | Nil = nil) : Result | Nil

Executes a process and returns its result.

Returns nil if the process fails to execute.

If error or output are Redirect::Pipe (default), this method captures the respective standard stream and returns it in the result.

Process.capture_result?(%w[echo foo]).try(&.output) # => "foo\n"
Process.capture_result?(%w[nonexist])               # => nil
Source
chroot(path : String) : Nil

Changes the root directory and the current working directory for the current process.

Available only on Unix-like operating systems.

Security: chroot on its own is not an effective means of mitigation. At minimum the process needs to also drop privileges as soon as feasible after the chroot. Changes to the directory hierarchy or file descriptors passed via recvmsg(2) from outside the chroot jail may allow a restricted process to escape, even if it is unprivileged.

Process.chroot("/var/empty")
Source
debugger_present?

Returns whether a debugger is attached to the current process.

Currently supported on Windows and Linux. Always returns false on other systems.

Source
exec(command : String, args : Enumerable(String) | Nil = nil, env : Env = nil, clear_env : Bool = false, shell : Bool = false, input : ExecStdio = Redirect::Inherit, output : ExecStdio = Redirect::Inherit, error : ExecStdio = Redirect::Inherit, chdir : Path | String | Nil = nil) : NoReturn

Replaces the current process with a new one. This function never returns.

Raises IO::Error if executing the command fails (for example if the executable doesn't exist).

Source
executable_path

Returns an absolute path to the executable file of the currently running program. This is in opposition to PROGRAM_NAME which may be a relative or absolute path, just the executable file name or a symlink.

The executable path will be canonicalized (all symlinks and relative paths will be expanded).

Returns nil if the file can't be found.

Source
exists?(pid : Int) : Bool

Returns true if the process identified by pid is valid for a currently registered process, false otherwise. Note that this returns true for a process in the zombie or similar state.

Source
exit(status : Int32 | Process::Status = 0) : NoReturn

Terminate the current process immediately. All open files, pipes and sockets are flushed and closed, all child processes are inherited by PID 1. This does not run any handlers registered with at_exit, use ::exit for that.

status is the exit status of the current process.

Source
find_executable(name : Path | String, path : String | Nil = ENV["PATH"]?, pwd : Path | String = Dir.current) : String | Nil

Searches an executable, checking for an absolute path, a path relative to pwd or absolute path, then eventually searching in directories declared in path.

Source
ignore_interrupts!

Ignores all interrupt requests. Removes any custom interrupt handler set with #on_terminate.

  • On Windows, interrupts generated by Ctrl + Break cannot be ignored in this way.
Source
on_interrupt

Installs handler as the new handler for interrupt requests. Removes any previously set interrupt handler.

The handler is executed on a fresh fiber every time an interrupt occurs.

  • On Unix-like systems, this traps SIGINT.
  • On Windows, this captures Ctrl + C and Ctrl + Break signals sent to a console application.
Source
on_terminate

Installs handler as the new handler for termination requests. Removes any previously set termination handler.

The handler is executed on a fresh fiber every time an interrupt occurs.

  • On Unix-like systems, this traps SIGINT, SIGHUP and SIGTERM.
  • On Windows, this captures Ctrl + C, Ctrl + Break, terminal close, windows logoff and shutdown signals sent to a console application.
wait_channel = Channel(Nil).new

Process.on_terminate do |reason|
  case reason
  when .interrupted?
    puts "terminating gracefully"
    wait_channel.close
  when .terminal_disconnected?
    puts "reloading configuration"
  when .session_ended?
    puts "terminating forcefully"
    Process.exit
  end
end

wait_channel.receive?
puts "bye"
Source
parse_arguments(line : String) : Array(String)

Splits the given line into individual command-line arguments in a platform-specific manner, unquoting tokens if necessary.

Equivalent to parse_arguments_posix on Unix-like systems. Equivalent to parse_arguments_windows on Windows.

Source
parse_arguments_posix(line : String) : Array(String)

Splits the given line into individual command-line arguments according to POSIX shell rules, unquoting tokens if necessary.

Raises ArgumentError if a quotation mark is unclosed.

Process.parse_arguments_posix(%q["foo bar" '\hello/' Fizz\ Buzz]) # => ["foo bar", "\\hello/", "Fizz Buzz"]

See https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_03

Source
parse_arguments_windows(line : String) : Array(String)

Splits the given line into individual command-line arguments according to Microsoft's standard C runtime, unquoting tokens if necessary.

Raises ArgumentError if a quotation mark is unclosed. Leading spaces in line are ignored. Otherwise, this method is equivalent to CommandLineToArgvW for some unspecified program name.

NOTE: This does not take strings that are passed to the CMD shell or used in a batch script.

Process.parse_arguments_windows(%q[foo"bar \\\"hello\\" Fizz\Buzz]) # => ["foobar \\\"hello\\", "Fizz\\Buzz"]
Source
pgid(pid : Int) : Int64

Returns the process group identifier of the process identified by pid.

Source
pgid

Returns the process group identifier of the current process.

Source
pid

Returns the process identifier of the current process.

Source
ppid

Returns the process identifier of the parent process of the current process.

On Windows, the parent is associated only at process creation time, and the system does not re-parent the current process if the parent terminates; thus Process.exists?(Process.ppid) is not guaranteed to be true.

Source
quote(args : Enumerable(String)) : String

Converts a sequence of strings to one joined string with each argument shell-quoted.

This is then safe to pass as part of the command when using shell: true or system().

NOTE: The actual return value is system-dependent, so it mustn't be relied on in other contexts. See also: quote_posix.

files = ["my file.txt", "another.txt"]
`grep -E 'fo+' -- #{Process.quote(files)}`
Source
quote(arg : String) : String

Shell-quotes one item, same as quote({arg}).

Source
quote_posix(args : Enumerable(String)) : String

Converts a sequence of strings to one joined string with each argument shell-quoted.

This is then safe to pass to a POSIX shell.

files = ["my file.txt", "another.txt"]
Process.quote_posix(files) # => "'my file.txt' another.txt"
Source
quote_posix(arg : String) : String

Shell-quotes one item, same as quote_posix({arg}).

Source
restore_interrupts!

Restores default handling of interrupt requests.

Source
run(command : String, args : Enumerable(String) | Nil = nil, env : Env = nil, clear_env : Bool = false, shell : Bool = false, input : Stdio = Redirect::Close, output : Stdio = Redirect::Close, error : Stdio = Redirect::Close, chdir : Path | String | Nil = nil) : Process::Status

Executes a child process and waits for it to complete, returning its status.

See Process.new for the meaning of the parameters.

Returns a Process::Status representing the child process' exit status. The global $? variable is set to the returned status.

Raises IO::Error if the execution itself fails (for example because the executable does not exist or is not executable).

Example:

status = Process.run("echo", ["hello"], output: Process::Redirect::Inherit)
# outputs "hello\n"
$?     # => Process::Status[0]
status # => Process::Status[0]
Source
run(args : Enumerable(String), *, env : Env | Nil = nil, clear_env : Bool = false, input : Stdio = Redirect::Close, output : Stdio = Redirect::Close, error : Stdio = Redirect::Close, chdir : Path | String | Nil = nil) : Process::Status

Executes a child process and waits for it to complete, returning its status.

See Process.new for the meaning of the parameters.

Returns a Process::Status representing the child process' exit status.

Raises IO::Error if the execution itself fails (for example because the executable does not exist or is not executable).

Example:

io = IO::Memory.new
status = Process.run(%w[echo hello], output: io)
io.to_s # => "hello\n"
status  # => Process::Status[0]
Source
run(*args : String, env : Env | Nil = nil, clear_env : Bool = false, input : Stdio = Redirect::Close, output : Stdio = Redirect::Close, error : Stdio = Redirect::Close, chdir : Path | String | Nil = nil) : Process::Status

Executes a child process and waits for it to complete, returning its status.

See Process.new for the meaning of the parameters.

Returns a Process::Status representing the child process' exit status.

Raises IO::Error if the execution itself fails (for example because the executable does not exist or is not executable).

Example:

io = IO::Memory.new
status = Process.run(%w[echo hello], output: io)
io.to_s # => "hello\n"
status  # => Process::Status[0]
Source
run(command : String, args : Enumerable(String) | Nil = nil, env : Env = nil, clear_env : Bool = false, shell : Bool = false, input : Stdio = Redirect::Pipe, output : Stdio = Redirect::Pipe, error : Stdio = Redirect::Pipe, chdir : Path | String | Nil = nil, &)

Executes a child process, yields the block, and then waits for it to finish.

See Process.new for the meaning of the parameters.

By default the process is configured to use pipes for input, output and error. These will be closed automatically at the end of the block.

Returns the block's value.

Raises IO::Error if the execution itself fails (for example because the executable does not exist or is not executable).

Example:

output = Process.run("echo", ["hello"]) do |process|
  process.output.gets_to_end
end
$?     # => Process::Status[0]
output # => "hello\n"
Source
run(args : Enumerable(String), *, env : Env = nil, clear_env : Bool = false, input : Stdio = Redirect::Pipe, output : Stdio = Redirect::Pipe, error : Stdio = Redirect::Pipe, chdir : Path | String | Nil = nil, & : Process -> _)

Executes a child process, yields the block, and then waits for it to finish.

See Process.new for the meaning of the parameters.

By default the process is configured to use pipes for input, output and error. These will be closed automatically at the end of the block.

Returns a tuple with the process' exit status and the block's output value.

Raises IO::Error if the execution itself fails (for example because the executable does not exist or is not executable).

Example:

status, result = Process.run(%w[echo hello]) do |process|
  process.output.gets_to_end
end
status # => Process::Status[0]
result # => "hello\n"
Source
run(*args : String, env : Env | Nil = nil, clear_env : Bool = false, input : Stdio = Redirect::Pipe, output : Stdio = Redirect::Pipe, error : Stdio = Redirect::Pipe, chdir : Path | String | Nil = nil, & : Process -> _)

Executes a child process, yields the block, and then waits for it to finish.

See Process.new for the meaning of the parameters.

By default the process is configured to use pipes for input, output and error. These will be closed automatically at the end of the block.

Returns a tuple with the process' exit status and the block's output value.

Raises IO::Error if the execution itself fails (for example because the executable does not exist or is not executable).

Example:

status, result = Process.run(%w[echo hello]) do |process|
  process.output.gets_to_end
end
status # => Process::Status[0]
result # => "hello\n"
Source
run?(args : Enumerable(String), *, env : Env | Nil = nil, clear_env : Bool = false, input : Stdio = Redirect::Close, output : Stdio = Redirect::Close, error : Stdio = Redirect::Close, chdir : Path | String | Nil = nil) : Process::Status | Nil

Executes a child process and waits for it to complete, returning its status.

See Process.new for the meaning of the parameters.

Returns a Process::Status representing the child process' exit status. The global $? variable is set to the returned status.

Returns nil if the execution itself fails (for example because the executable does not exist or is not executable).

Example:

Process.run?(["true"])        # => Process::Status[0]
Process.run?(["nonexistent"]) # => nil
Source
run?(*args : String, env : Env | Nil = nil, clear_env : Bool = false, input : Stdio = Redirect::Close, output : Stdio = Redirect::Close, error : Stdio = Redirect::Close, chdir : Path | String | Nil = nil) : Process::Status | Nil

Executes a child process and waits for it to complete, returning its status.

See Process.new for the meaning of the parameters.

Returns a Process::Status representing the child process' exit status. The global $? variable is set to the returned status.

Returns nil if the execution itself fails (for example because the executable does not exist or is not executable).

Example:

Process.run?(["true"])        # => Process::Status[0]
Process.run?(["nonexistent"]) # => nil
Source
signal(signal : Signal, pid : Int) : Nil

Sends signal to the process identified by pid.

Source
times

Returns a Tms for the current process. For the children times, only those of terminated children are returned on Unix; they are zero on Windows.

Source

Instance methods

close

Closes any system resources (e.g. pipes) held for the child process.

Source
error

A pipe to this process' error. Raises if a pipe wasn't asked when creating the process.

Source
error?

A pipe to this process' error. Raises if a pipe wasn't asked when creating the process.

Source
exists?

Whether the process is still registered in the system. Note that this returns true for processes in the zombie or similar state.

Source
finalize
Source
input

A pipe to this process' input. Raises if a pipe wasn't asked when creating the process.

Source
input?

A pipe to this process' input. Raises if a pipe wasn't asked when creating the process.

Source
output

A pipe to this process' output. Raises if a pipe wasn't asked when creating the process.

Source
output?

A pipe to this process' output. Raises if a pipe wasn't asked when creating the process.

Source
pid

Returns the process identifier of this process.

Source
signal(signal : Signal) : Nil

Sends signal to this process.

NOTE: #terminate is preferred over signal(Signal::TERM) and signal(Signal::KILL) as a portable alternative which also works on Windows.

Source
terminate(*, graceful : Bool = true) : Nil

Asks this process to terminate.

If graceful is true, prefers graceful termination over abrupt termination if supported by the system.

  • On Unix-like systems, this causes Signal::TERM to be sent to the process instead of Signal::KILL.
  • On Windows, this parameter has no effect and graceful termination is unavailable. The terminated process has an exit status of 1.
Source
terminated?

Whether this process is already terminated.

Source
wait

Waits for this process to complete and closes any pipes.

Source

Nested types