Process - Crystal 1.20.1

# class Process

- Process
- Reference
- Object

##
Defined in:

kernel.cr
process.cr:1
process.cr:14
process/capture.cr
process/executable_path.cr:5
process/executable_path.cr:105
process/shell.cr

##
Constant Summary

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.

- .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)

  Creates and executes a child process.

  EXPERIMENTAL

##
Class Method Summary

- .capture(args : Enumerable(String), *, env : Env = 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.

  EXPERIMENTAL

- .capture?(args : Enumerable(String), *, env : Env = 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.

  EXPERIMENTAL

- .capture_result(args : Enumerable(String), *, env : Env = 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.

  EXPERIMENTAL

- .capture_result?(args : Enumerable(String), *, env : Env = 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.

  EXPERIMENTAL

- .chroot(path : String) : Nil

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

- .debugger_present? : Bool

  Returns whether a debugger is attached to the current process.

  EXPERIMENTAL

- .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.

- .executable_path : String | Nil

  Returns an absolute path to the executable file of the currently running program.

- .exists?(pid : Int) : Bool

  Returns `true` if the process identified by pid is valid for a currently registered process, `false` otherwise.

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

  Terminate the current process immediately.

- .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.

- .ignore_interrupts! : Nil

  Ignores all interrupt requests.

- .on_interrupt(&handler : -> ) : Nil

  Installs handler as the new handler for interrupt requests.

  DEPRECATED Use `#on_terminate` instead

- .on_terminate(&handler : Process::ExitReason -> ) : Nil

  Installs handler as the new handler for termination requests.

- .parse_arguments(line : String) : Array(String)

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

- .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.

- .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.

- .pgid(pid : Int) : Int64

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

- .pgid : Int64

  Returns the process group identifier of the current process.

- .pid : Int64

  Returns the process identifier of the current process.

- .ppid : Int64

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

- .quote(args : Enumerable(String)) : String

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

- .quote(arg : String) : String

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

- .quote_posix(args : Enumerable(String)) : String

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

- .quote_posix(arg : String) : String

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

- .restore_interrupts! : Nil

  Restores default handling of interrupt requests.

- .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.

- .run(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) : Process::Status

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

  EXPERIMENTAL

- .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.

- .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.

  EXPERIMENTAL

- .run?(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) : Process::Status | Nil

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

  EXPERIMENTAL

- .signal(signal : Signal, pid : Int) : Nil

  Sends signal to the process identified by pid.

- .times : Tms

  Returns a `Tms` for the current process.

##
Instance Method Summary

- #close : Nil

  Closes any system resources (e.g.

- #error : IO::FileDescriptor

  A pipe to this process' error.

- #error? : IO::FileDescriptor | Nil

  A pipe to this process' error.

- #exists? : Bool

  Whether the process is still registered in the system.

- #finalize : Nil
- #input : IO::FileDescriptor

  A pipe to this process' input.

- #input? : IO::FileDescriptor | Nil

  A pipe to this process' input.

- #output : IO::FileDescriptor

  A pipe to this process' output.

- #output? : IO::FileDescriptor | Nil

  A pipe to this process' output.

- #pid : Int64

  Returns the process identifier of this process.

- #signal(signal : Signal) : Nil

  Sends signal to this process.

- #terminate(*, graceful : Bool = true) : Nil

  Asks this process to terminate.

- #terminated? : Bool

  Whether this process is already terminated.

- #wait : Process::Status

  Waits for this process to complete and closes any pipes.

### Instance methods inherited from class `Reference`

==(other : self)
==(other : JSON::Any)
==(other : YAML::Any)
==(other) ==, dup dup, hash(hasher) hash, initialize initialize, inspect(io : IO) : Nil inspect, object_id : UInt64 object_id, pretty_print(pp) : Nil pretty_print, same?(other : Reference) : Bool
same?(other : Nil) same?, to_s(io : IO) : Nil to_s

### Constructor methods inherited from class `Reference`

new new, unsafe_construct(address : Pointer, *args, **opts) : self unsafe_construct

### Class methods inherited from class `Reference`

pre_initialize(address : Pointer) pre_initialize

### Instance methods inherited from class `Object`

! : Bool !, !=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other) ===, =~(other) =~, as(type : Class) as, as?(type : Class) as?, class class, dup dup, hash(hasher)
hash hash, in?(collection : Object) : Bool
in?(*values : Object) : Bool in?, inspect(io : IO) : Nil
inspect : String inspect, is_a?(type : Class) : Bool is_a?, itself itself, nil? : Bool nil?, not_nil!(message)
not_nil! not_nil!, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, responds_to?(name : Symbol) : Bool responds_to?, tap(&) tap, to_json(io : IO) : Nil
to_json : String to_json, to_pretty_json(indent : String = " ") : String
to_pretty_json(io : IO, indent : String = " ") : Nil to_pretty_json, to_s(io : IO) : Nil
to_s : String to_s, to_yaml(io : IO) : Nil
to_yaml : String to_yaml, try(&) try, unsafe_as(type : T.class) forall T unsafe_as

### Class methods inherited from class `Object`

from_json(string_or_io : String | IO, root : String)
from_json(string_or_io : String | IO) from_json, from_yaml(string_or_io : String | IO) from_yaml

### Macros inherited from class `Object`

class_getter(*names, &block) class_getter, class_getter!(*names) class_getter!, class_getter?(*names, &block) class_getter?, class_property(*names, &block) class_property, class_property!(*names) class_property!, class_property?(*names, &block) class_property?, class_setter(*names) class_setter, def_clone def_clone, def_equals(*fields) def_equals, def_equals_and_hash(*fields) def_equals_and_hash, def_hash(*fields) def_hash, delegate(*methods, to object) delegate, forward_missing_to(delegate) forward_missing_to, getter(*names, &block) getter, getter!(*names) getter!, getter?(*names, &block) getter?, property(*names, &block) property, property!(*names) property!, property?(*names, &block) property?, setter(*names) setter

##
Constructor Detail

def self.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_executable`can help with looking up a command in a custom`PATH`.

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.

def self.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) #

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_executable`can help with looking up a command in a custom`PATH`.

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.

EXPERIMENTAL

##
Class Method Detail

def self.capture(args : Enumerable(String), *, env : Env = 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

EXPERIMENTAL

def self.capture?(args : Enumerable(String), *, env : Env = 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

EXPERIMENTAL

def self.capture_result(args : Enumerable(String), *, env : Env = 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

EXPERIMENTAL

def self.capture_result?(args : Enumerable(String), *, env : Env = 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

EXPERIMENTAL

def self.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")

def self.debugger_present? : Bool #

Returns whether a debugger is attached to the current process.

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

EXPERIMENTAL

def self.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).

def self.executable_path : String | Nil #

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.

def self.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.

def self.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.

def self.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.

def self.ignore_interrupts! : Nil #

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.

def self.on_interrupt(&handler : -> ) : Nil #

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.

DEPRECATED Use `#on_terminate` instead

def self.on_terminate(&handler : Process::ExitReason -> ) : Nil #

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"

def self.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.

def self.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

def self.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"]

def self.pgid(pid : Int) : Int64 #

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

def self.pgid : Int64 #

Returns the process group identifier of the current process.

def self.pid : Int64 #

Returns the process identifier of the current process.

def self.ppid : Int64 #

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.

def self.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)}`

def self.quote(arg : String) : String #

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

def self.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"

def self.quote_posix(arg : String) : String #

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

def self.restore_interrupts! : Nil #

Restores default handling of interrupt requests.

def self.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]

def self.run(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) : 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]

EXPERIMENTAL

def self.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"

def self.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"

EXPERIMENTAL

def self.run?(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) : 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

EXPERIMENTAL

def self.signal(signal : Signal, pid : Int) : Nil #

Sends signal to the process identified by pid.

def self.times : Tms #

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.

##
Instance Method Detail

def close : Nil #

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

def error : IO::FileDescriptor #

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

def error? : IO::FileDescriptor | Nil #

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

def exists? : Bool #

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

def finalize : Nil #
def input : IO::FileDescriptor #

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

def input? : IO::FileDescriptor | Nil #

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

def output : IO::FileDescriptor #

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

def output? : IO::FileDescriptor | Nil #

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

def pid : Int64 #

Returns the process identifier of this process.

def 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.

def 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.

def terminated? : Bool #

Whether this process is already terminated.

def wait : Process::Status #

Waits for this process to complete and closes any pipes.