### Create and start a child process Source: https://context7.com/enkessler/childprocess/llms.txt Use ChildProcess.build to configure a process and start to launch it. Arguments must be provided as strings. ```ruby require 'childprocess' # Basic process creation process = ChildProcess.build("ruby", "-e", "puts 'Hello World'") # Process with multiple arguments process = ChildProcess.build("ls", "-la", "/tmp") # Shell command (must invoke shell explicitly) process = ChildProcess.build("sh", "-c", "echo $HOME && ls -la") # Windows shell command process = ChildProcess.build("cmd.exe", "/c", "dir") # Start the process process.start # Wait for completion process.wait # Get exit code puts process.exit_code #=> 0 ``` -------------------------------- ### Configure and launch a process Source: https://context7.com/enkessler/childprocess/llms.txt Configure environment variables and working directories before calling start. The start method returns the process object, allowing for method chaining. ```ruby require 'childprocess' process = ChildProcess.build("sleep", "5") # Configure before starting process.cwd = "/tmp" process.environment["MY_VAR"] = "value" # Start returns self, enabling method chaining process.start # Check status puts process.started? #=> true puts process.alive? #=> true puts process.pid #=> 12345 # Process is now running in background ``` -------------------------------- ### Enable Writing to Child Process Stdin Source: https://context7.com/enkessler/childprocess/llms.txt Set `duplex = true` to enable writing to the child's stdin. `process.io.stdin` becomes available as a writable IO object after starting. ```ruby require 'childprocess' require 'tempfile' process = ChildProcess.build("cat") out = Tempfile.new("duplex-output") out.sync = true process.io.stdout = out process.io.stderr = out process.duplex = true # Enable stdin writing process.start # Write to the child's stdin process.io.stdin.puts "Hello from parent!" process.io.stdin.puts "Another line" process.io.stdin.close # Important: close stdin to signal EOF process.poll_for_exit(5) out.rewind puts out.read #=> Hello from parent! #=> Another line ``` -------------------------------- ### Error Handling with ChildProcess Exceptions Source: https://context7.com/enkessler/childprocess/llms.txt Childprocess defines several exception classes for error handling: `LaunchError` when a process can't start, `TimeoutError` when `poll_for_exit` times out, and `InvalidEnvironmentVariable` for malformed environment variables. ```ruby require 'childprocess' # Handle launch errors begin process = ChildProcess.build("nonexistent_command_xyz") process.start rescue ChildProcess::LaunchError => e puts "Failed to start process: #{e.message}" end # Handle timeout errors begin process = ChildProcess.build("sleep", "100") process.start process.poll_for_exit(1) rescue ChildProcess::TimeoutError puts "Process didn't exit in time" process.stop end # Handle invalid environment variables begin process = ChildProcess.build("echo", "test") process.environment["INVALID\0VAR"] = "value" # Null byte not allowed process.start rescue ChildProcess::InvalidEnvironmentVariable => e puts "Invalid env var: #{e.message}" end ``` -------------------------------- ### Prevent File Descriptor Inheritance with ChildProcess.close_on_exec Source: https://context7.com/enkessler/childprocess/llms.txt Ensures that a file descriptor is not inherited by child processes using `ChildProcess.close_on_exec(file_descriptor)`. This is useful for open files or sockets that should not be accessible to children. The example demonstrates preventing a `TCPServer` socket from being inherited. ```ruby require 'childprocess' require 'socket' server = TCPServer.new("127.0.0.1", 8080) # Prevent child from inheriting this socket ChildProcess.close_on_exec(server) process = ChildProcess.build("ruby", "-e", "sleep 5") process.io.inherit! process.start # Safe to close server - child doesn't hold a reference server.close # Port 8080 is now free even though child is running process.wait ``` -------------------------------- ### Manage basic process lifecycle in Ruby Source: https://github.com/enkessler/childprocess/blob/master/README.md Demonstrates building, configuring IO, setting environment variables, and controlling process execution. ```ruby process = ChildProcess.build("ruby", "-e", "sleep") # inherit stdout/stderr from parent... process.io.inherit! # ...or pass an IO process.io.stdout = Tempfile.new("child-output") # modify the environment for the child process.environment["a"] = "b" process.environment["c"] = nil # set the child's working directory process.cwd = '/some/path' # start the process process.start # check process status process.alive? #=> true process.exited? #=> false # wait indefinitely for process to exit... process.wait process.exited? #=> true # get the exit code process.exit_code #=> 0 # ...or poll for exit + force quit begin process.poll_for_exit(10) rescue ChildProcess::TimeoutError process.stop # tries increasingly harsher methods to kill the process. end ``` -------------------------------- ### process.start Source: https://context7.com/enkessler/childprocess/llms.txt Launches the configured child process and returns self. ```APIDOC ## process.start ### Description Launches the configured child process and returns self. All configuration (environment, cwd, io) must be set before calling this method. ### Response - **self** (Object) - The process instance. ``` -------------------------------- ### ChildProcess.build Source: https://context7.com/enkessler/childprocess/llms.txt Creates and returns a new process object configured with the specified command and arguments. ```APIDOC ## ChildProcess.build ### Description Creates and returns a new process object configured with the specified command and arguments. The process is not started until you explicitly call start. ### Parameters - **args** (String) - Required - The command and arguments to execute. ### Response - **process** (Object) - A new process object. ``` -------------------------------- ### process.environment Source: https://context7.com/enkessler/childprocess/llms.txt Configures environment variables for the child process. Setting a key to nil unsets an inherited variable. ```APIDOC ## process.environment ### Description A hash-like object for setting environment variables for the child process. Changes only affect the child process, not the parent. ### Parameters #### Request Body - **key** (string/symbol) - Required - The environment variable name - **value** (string/nil) - Required - The value to set, or nil to unset ``` -------------------------------- ### Platform Detection Methods in ChildProcess Source: https://context7.com/enkessler/childprocess/llms.txt Utility methods to detect the current platform and Ruby environment. Useful for writing cross-platform code. ```ruby require 'childprocess' puts ChildProcess.platform #=> :linux, :macosx, :windows, etc. puts ChildProcess.platform_name #=> "x86_64-linux" puts ChildProcess.unix? #=> true (on Unix-like systems) puts ChildProcess.windows? #=> true (on Windows) puts ChildProcess.linux? #=> true (on Linux) puts ChildProcess.jruby? #=> true (if running JRuby) ``` -------------------------------- ### Set Environment Variables for Child Process Source: https://context7.com/enkessler/childprocess/llms.txt Set environment variables for a child process using a hash-like object. Setting a variable to nil unsets it. Changes do not affect the parent process. ```ruby require 'childprocess' process = ChildProcess.build("ruby", "-e", "puts ENV['FOO']; puts ENV['BAR']") # Set environment variables (strings or symbols) process.environment["FOO"] = "hello" process.environment[:BAR] = "world" # Unset an inherited variable process.environment["HOME"] = nil # Capture output to see the result out = Tempfile.new("env-output") process.io.stdout = out process.start process.wait out.rewind puts out.read #=> hello #=> world ``` -------------------------------- ### process.io.inherit! Source: https://context7.com/enkessler/childprocess/llms.txt Configures the child process to inherit stdout and stderr from the parent. ```APIDOC ## process.io.inherit! ### Description Makes the child process inherit stdout and stderr from the parent process. Output from the child will appear directly in the parent's terminal. ``` -------------------------------- ### Configure custom logger Source: https://github.com/enkessler/childprocess/blob/master/README.md Redirects internal library logs to a custom Logger instance. ```ruby logger = Logger.new('logfile.log') logger.level = Logger::DEBUG ChildProcess.logger = logger ``` -------------------------------- ### process.duplex Source: https://context7.com/enkessler/childprocess/llms.txt Enables stdin writing for the child process. ```APIDOC ## process.duplex ### Description Set duplex = true to enable writing to the child's stdin. After starting, process.io.stdin becomes available as a writable IO object. ### Parameters #### Request Body - **duplex** (boolean) - Required - Set to true to enable stdin writing ``` -------------------------------- ### Set Working Directory for Child Process Source: https://context7.com/enkessler/childprocess/llms.txt Set the current working directory for the child process. The parent's working directory remains unaffected. ```ruby require 'childprocess' process = ChildProcess.build("ruby", "-e", "puts Dir.pwd") # Set child's working directory process.cwd = "/tmp" out = Tempfile.new("cwd-output") process.io.stdout = out process.start process.wait out.rewind puts out.read #=> /tmp ``` -------------------------------- ### Ensure process tree termination Source: https://github.com/enkessler/childprocess/blob/master/README.md Sets the process as a leader to ensure the entire tree is terminated when killed. ```ruby process = ChildProcess.build(*args) process.leader = true process.start ``` -------------------------------- ### Check process status Source: https://context7.com/enkessler/childprocess/llms.txt Use alive?, exited?, and crashed? to monitor the state of a process. crashed? returns true if the process exits with a non-zero status. ```ruby require 'childprocess' # Successful process success = ChildProcess.build("ruby", "-e", "exit 0") success.start success.wait puts success.alive? #=> false puts success.exited? #=> true puts success.crashed? #=> false puts success.exit_code #=> 0 # Failing process failure = ChildProcess.build("ruby", "-e", "exit 1") failure.start failure.wait puts failure.crashed? #=> true puts failure.exit_code #=> 1 ``` -------------------------------- ### Execute Command in Shell on Windows Source: https://github.com/enkessler/childprocess/wiki/Using-ChildProcess-with-Windows When ChildProcess does not execute commands in a shell by default, use this pattern to explicitly run commands via 'cmd.exe /c' on Windows. ```ruby process = ChildProcess.build("cmd.exe", "/c", "echo 'Hello World'") ``` -------------------------------- ### Capture process output via pipe Source: https://github.com/enkessler/childprocess/blob/master/README.md Uses IO.pipe to capture stdout from a subprocess in a thread-safe manner. ```ruby r, w = IO.pipe begin process = ChildProcess.build("sh" , "-c", "for i in {1..3}; do echo $i; sleep 1; done") process.io.stdout = w process.start # This results in a subprocess inheriting the write end of the pipe. # Close parent's copy of the write end of the pipe so when the child # process closes its write end of the pipe the parent receives EOF when # attempting to read from it. If the parent leaves its write end open, it # will not detect EOF. w.close thread = Thread.new do begin loop do print r.readpartial(16384) end rescue EOFError # Child has closed the write end of the pipe end end process.wait thread.join ensure r.close end ``` -------------------------------- ### Inherit Parent's I/O Streams Source: https://context7.com/enkessler/childprocess/llms.txt Make the child process inherit stdout and stderr from the parent. Output from the child will appear directly in the parent's terminal. ```ruby require 'childprocess' process = ChildProcess.build("ruby", "-e", "puts 'visible output'; warn 'visible error'") # Inherit parent's stdout/stderr process.io.inherit! process.start process.wait # Output appears directly in terminal: # visible output # visible error ``` -------------------------------- ### Read Process Output in Real-time with Threading Source: https://context7.com/enkessler/childprocess/llms.txt Stream output from long-running processes in real-time using pipes and threads. Ensure the parent's write end of the pipe is closed to detect EOF. ```ruby require 'childprocess' r, w = IO.pipe begin process = ChildProcess.build("sh", "-c", "for i in 1 2 3; do echo $i; sleep 1; done") process.io.stdout = w process.start # Close parent's write end so EOF is detected when child closes w.close # Read output in a separate thread reader = Thread.new do begin loop { print r.readpartial(1024) } rescue EOFError # Child closed the pipe end end process.wait reader.join ensure r.close end # Output (with 1-second delays): # 1 # 2 # 3 ``` -------------------------------- ### process.io.stdout / process.io.stderr Source: https://context7.com/enkessler/childprocess/llms.txt Redirects child process output streams to files or pipes. ```APIDOC ## process.io.stdout / process.io.stderr ### Description Redirect the child's stdout and/or stderr to file objects, Tempfiles, or pipe write ends. ### Parameters #### Request Body - **stream** (IO/File) - Required - The target object to receive the stream output ``` -------------------------------- ### process.leader Source: https://context7.com/enkessler/childprocess/llms.txt Configures the child process as a process group leader. ```APIDOC ## process.leader ### Description Set leader = true to make the child process the leader of a new process group. When stopped, all descendants will also be terminated. ### Parameters #### Request Body - **leader** (boolean) - Required - Set to true to enable process group leadership ``` -------------------------------- ### process.cwd Source: https://context7.com/enkessler/childprocess/llms.txt Sets the current working directory for the child process. ```APIDOC ## process.cwd ### Description Sets the current working directory for the child process. The parent's working directory remains unchanged. ### Parameters #### Request Body - **path** (string) - Required - The directory path for the child process ``` -------------------------------- ### Pipe output between processes Source: https://github.com/enkessler/childprocess/blob/master/README.md Connects the stdout of one process to the stdin of another. ```ruby search = ChildProcess.build("grep", '-E', %w(redis memcached).join('|')) search.duplex = true # sets up pipe so search.io.stdin will be available after .start search.io.stdout = $stdout search.start listing = ChildProcess.build("ps", "aux") listing.io.stdout = search.io.stdin listing.start listing.wait search.io.stdin.close search.wait ``` -------------------------------- ### Kill Entire Process Tree Source: https://context7.com/enkessler/childprocess/llms.txt Set `leader = true` to make the child process the leader of a new process group. When stopped, all descendants will also be terminated. ```ruby require 'childprocess' # Parent spawns a child that spawns a grandchild process = ChildProcess.build("ruby", "-e", <<-CODE) child_pid = spawn("sleep 100") Process.detach(child_pid) sleep 100 CODE process.leader = true # Create new process group process.start sleep 1 # Let the process tree establish # Stopping kills the entire process tree (parent + grandchild) process.stop puts process.exited? #=> true ``` -------------------------------- ### Pipe Output Between Processes Source: https://context7.com/enkessler/childprocess/llms.txt Chain multiple child processes by connecting the stdout of one to the stdin of another, similar to shell pipes. Ensure stdin is closed to signal EOF. ```ruby require 'childprocess' # Create a pipeline: ps aux | grep ruby grep_process = ChildProcess.build("grep", "ruby") grep_process.duplex = true # Enable stdin grep_process.io.stdout = $stdout grep_process.start ps_process = ChildProcess.build("ps", "aux") ps_process.io.stdout = grep_process.io.stdin # Pipe ps output to grep input ps_process.start ps_process.wait grep_process.io.stdin.close # Signal EOF to grep grep_process.wait ``` -------------------------------- ### Configure Custom Logging with ChildProcess.logger Source: https://context7.com/enkessler/childprocess/llms.txt Configure a custom logger for debugging and error output by assigning a `Logger` instance to `ChildProcess.logger`. By default, logs go to stderr at INFO level. Reset to default by setting `ChildProcess.logger = nil`. ```ruby require 'childprocess' require 'logger' # Use custom logger logger = Logger.new('childprocess.log') logger.level = Logger::DEBUG ChildProcess.logger = logger # Now all childprocess operations will log to the file process = ChildProcess.build("echo", "hello") process.start process.wait # Reset to default logger ChildProcess.logger = nil ``` -------------------------------- ### Detach process from parent Source: https://github.com/enkessler/childprocess/blob/master/README.md Allows a process to run independently of the parent process. ```ruby process = ChildProcess.build("sleep", "10") process.detach = true process.start ``` -------------------------------- ### Terminate a process Source: https://context7.com/enkessler/childprocess/llms.txt Use stop to forcibly terminate a process. It uses escalating signals and accepts an optional timeout parameter. ```ruby require 'childprocess' process = ChildProcess.build("ruby", "-e", "trap('TERM') { }; sleep 100") process.start # Stop with default 3-second timeout between attempts process.stop # Or specify custom timeout # process.stop(5) # Wait 5 seconds before escalating puts process.exited? #=> true ``` -------------------------------- ### process.stop Source: https://context7.com/enkessler/childprocess/llms.txt Forcibly terminates the process. ```APIDOC ## process.stop ### Description Forcibly terminates the process using increasingly harsher methods if necessary. ### Parameters - **timeout** (Integer) - Optional - Time to wait between escalation attempts (default 3 seconds). ``` -------------------------------- ### Run Process Independently with detach = true Source: https://context7.com/enkessler/childprocess/llms.txt Set `detach = true` to allow the child process to continue running even after the parent exits. The child becomes independent of the parent's lifecycle. The child process will create `/tmp/done.txt` after 30 seconds. ```ruby require 'childprocess' process = ChildProcess.build("ruby", "-e", "sleep 30; File.write('/tmp/done.txt', 'completed')") process.detach = true # Child survives parent exit process.start puts "Child PID: #{process.pid}" puts "Parent exiting, child will continue..." # Parent can exit here, child keeps running # After 30 seconds, /tmp/done.txt will be created ``` -------------------------------- ### Write to process stdin Source: https://github.com/enkessler/childprocess/blob/master/README.md Enables duplex mode to send data to the child process's standard input. ```ruby process = ChildProcess.build("cat") out = Tempfile.new("duplex") out.sync = true process.io.stdout = process.io.stderr = out process.duplex = true # sets up pipe so process.io.stdin will be available after .start process.start process.io.stdin.puts "hello world" process.io.stdin.close process.poll_for_exit(exit_timeout_in_seconds) out.rewind out.read #=> "hello world\n" ``` -------------------------------- ### Wait for process completion Source: https://context7.com/enkessler/childprocess/llms.txt Use wait to block the current thread until the child process finishes. It returns the process exit code. ```ruby require 'childprocess' process = ChildProcess.build("ruby", "-e", "sleep 2; exit 0") process.start puts "Waiting for process..." exit_code = process.wait puts "Process finished with exit code: #{exit_code}" #=> 0 puts process.exited? #=> true puts process.alive? #=> false ``` -------------------------------- ### Redirect Child Process Output Streams Source: https://context7.com/enkessler/childprocess/llms.txt Redirect the child's stdout and/or stderr to file objects, Tempfiles, or pipe write ends for programmatic output capture. ```ruby require 'childprocess' require 'tempfile' process = ChildProcess.build("ruby", "-e", <<-CODE) STDOUT.puts "standard output" STDERR.puts "error output" CODE stdout_file = Tempfile.new("stdout") stderr_file = Tempfile.new("stderr") process.io.stdout = stdout_file process.io.stderr = stderr_file process.start process.wait stdout_file.rewind stderr_file.rewind puts "STDOUT: #{stdout_file.read}" #=> STDOUT: standard output puts "STDERR: #{stderr_file.read}" #=> STDERR: error output stdout_file.close stderr_file.close ``` -------------------------------- ### Invoke shell commands explicitly Source: https://github.com/enkessler/childprocess/blob/master/README.md Workaround for executing shell-dependent commands by specifying the interpreter. ```ruby ChildProcess.build("cmd.exe", "/c", "bundle") ChildProcess.build("ruby", "-S", "bundle") ``` -------------------------------- ### process.wait Source: https://context7.com/enkessler/childprocess/llms.txt Blocks the current thread until the child process terminates. ```APIDOC ## process.wait ### Description Blocks the current thread until the child process terminates. ### Response - **exit_code** (Integer) - The exit code of the process. ``` -------------------------------- ### process.poll_for_exit Source: https://context7.com/enkessler/childprocess/llms.txt Polls for process exit with a specified timeout. ```APIDOC ## process.poll_for_exit ### Description Polls for process exit with a specified timeout in seconds. Raises ChildProcess::TimeoutError if the process doesn't exit within the timeout. ### Parameters - **timeout** (Integer) - Required - Timeout in seconds. ``` -------------------------------- ### Poll for process exit with timeout Source: https://context7.com/enkessler/childprocess/llms.txt Use poll_for_exit to wait for a process with a specific timeout. It raises ChildProcess::TimeoutError if the timeout is exceeded. ```ruby require 'childprocess' process = ChildProcess.build("sleep", "10") process.start begin # Wait up to 2 seconds for exit process.poll_for_exit(2) puts "Process exited normally" rescue ChildProcess::TimeoutError puts "Process timed out, stopping..." process.stop # Forcibly terminate end puts process.exited? #=> true puts process.exit_code #=> -9 (killed) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.