What is the difference between the following Ruby methods?
exec
, system
and %x()
or Backticks
I know they are used to execute terminal commands programmatically via Ruby, but I'd like to know why there are three different ways to do this.
What is the difference between the following Ruby methods?
exec
, system
and %x()
or Backticks
I know they are used to execute terminal commands programmatically via Ruby, but I'd like to know why there are three different ways to do this.
They do different things.
exec
replaces the current process with the new process and never returns.system
invokes another process and returns its exit value to the current process. Using backticks invokes another process and returns the output of that process to the current process.Here's a flowchart based on this answer. See also, using
script
to emulate a terminal.system
The
system
method calls a system program. You have to provide the command as a string argument to this method. For example:The invoked program will use the current
STDIN
,STDOUT
andSTDERR
objects of your Ruby program. In fact, the actual return value is eithertrue
,false
ornil
. In the example the date was printed through the IO object ofSTDIN
. The method will returntrue
if the process exited with a zero status,false
if the process exited with a non-zero status andnil
if the execution failed.Another side effect is that the global variable
$?
is set to aProcess::Status
object. This object will contain information about the call itself, including the process identifier (PID) of the invoked process and the exit status.Backticks
Backticks (``) call a system program and return its output. As opposed to the first approach, the command is not provided through a string, but by putting it inside a backticks pair.
The global variable
$?
is set through the backticks, too. With backticks you can also make use string interpolation.%x()
Using
%x
is an alternative to the backticks style. It will return the output, too. Like its relatives%w
and%q
(among others), any delimiter will suffice as long as bracket-style delimiters match. This means%x(date)
,%x{date}
and%x-date-
are all synonyms. Like backticks%x
can make use of string interpolation.exec
By using
Kernel#exec
the current process (your Ruby script) is replaced with the process invoked throughexec
. The method can take a string as argument. In this case the string will be subject to shell expansion. When using more than one argument, then the first one is used to execute a program and the following are provided as arguments to the program to be invoked.Open3.popen3
Sometimes the required information is written to standard input or standard error and you need to get control over those as well. Here
Open3.popen3
comes in handy: