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
