liveBook · Manning

System program

As explained in The Well-Grounded Rubyist, Fourth Edition

An external program is a separately executed operating-system process that another program can communicate with.

A system program is an external operating-system process that Ruby starts and communicates with. Ruby can inherit its standard streams, capture its output, replace the current process, or exchange data through I/O handles. section 14.6.1 section 14.6.2

Ruby provides several levels of interaction:

  • Use system with a command and arguments; it returns a success value, uses the current STDIN, STDOUT, and STDERR, and records status in the thread-local $?. section 14.6.1
  • Use backticks or %x to return the external program's output as a Ruby string; failures still update $?, while a nonexistent backtick command raises an error. section 14.6.1
  • Use exec when Ruby should be replaced by the process running the specified command. section 14.6.1
  • Use open with a pipe for a two-way I/O connection, or Open3.popen3 for separate handles to standard input, output, and error. section 14.6.2

Capture a command's output

d = `date` returns a string containing the command's output, which can then be printed with puts. By contrast, system("date") prints directly and returns true on success. section 14.6.1

>> require 'open3' 1
=> true
>> stdin, stdout, stderr = Open3.popen3("cat")     2
=> [#<IO:fd 7>, #<IO:fd 8>, #<IO:fd 10>,    3
#<Process::Waiter:0x00000001286b1ab0 sleep>] 3
>> stdin.puts("Hi.\nBye")                    4
=> nil
>> stdout.gets              5
=> "Hi.\n"
>> stdout.gets
=> "Bye\n"

Open3.popen3 returns separate handles, allowing Ruby to write to cat's standard input and read its standard output independently. section 14.6.2

How The Well-Grounded Rubyist, Fourth Edition covers it

How deep it goes
Explains inherited streams, captured output, process status, pipes, and separate I/O handles, but defers platform-specific library details.
Examples
Uses date, cat, grep, nonexistent commands, open pipes, and an Open3.popen3 session to demonstrate execution and communication.
What it assumes
Assumes basic Ruby expressions, I/O, threads, and operating-system streams while building from simple commands toward coordinated communication.
What you can do after
Apply it via Ruby methods to run commands, capture output, inspect status, or exchange data through process streams.
How it connects
Connects system programs with system, backticks, exec, standard streams, process status, pipes, threads, and I/O handles.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Well-Grounded Rubyist, Fourth Edition. The section links point to the parts of the book it draws on.