Execution of shell code in Ruby scripts
All other methods to execute shell commands have signficant downsides, such as:
- They do not tell you if the command has succeeded
- They only return STDOUT, but not STDERR with error messages
- They don't let you choose whether command output appears on the screen or not
- They allow to inject code that will be interpreted by the shell
- You always need to wait for a long-running process to finish before you can inspect or echo its output
This is just a reference for legacy code. For new code, always use
or backticks – quick and easy
Returns the standard output of running the given command in a subshell. This is an alias for `...`, and you can use string interpolation.
name = 'ls'
It does not escape anything you inject in the string.
If you want to find out if the call was successful you can ask
– when you want to know how it went
exec, but executes the given command in a subshell. Your script will go on. Returns:
trueif the command gives zero exit status
falsefor non zero exit status
if system 'cp', '/full/path/to/my_file', '/target/directory'
puts "You made it!"
puts "Something went wrong"
system (as well as
exec) has two distinct argument patterns:
a single string argument is passed to the shell like "Hey, lets pretend the user typed this. Please run it!"Copy
>> system 'echo *'
This is equivalent to:Copy
$ echo *
Note how the asterisk is interpreted by the shell, as would any other characters (like a semicolon which separates commands).
Output will be something like:Copy
file1 file2 file3
when passed multiple arguments, Ruby will take the first as command and find it on the $PATH. It then invokes it, passing the remaining arguments as Strings:Copy
system 'echo', '*'
This is equivalent to:Copy
$ /bin/echo '*'
Since Ruby is passing all arguments as Strings, there will be no wildcard expansion or the like.
Output will be:Copy
You cannot freely mix these styles, and
system will fail when passing it invalid arguments:
system 'bundle exec rails server', '-p 3000' # fails and returns nil
This is equivalent to running a command called "
bundle exec rails" (including spaces in its filename). There is usually no such command anywhere on the
Note that you should prefer the 2nd approach (list of arguments instead of putting them into a single command) unless you absolutely know what you are doing.
– the last thing you do
Replaces the current process. Take care: when an
exec command exits, it exits your script as well; i.e.
exec will be the last statement executed in your Ruby script. Output is written to
SystemCallError if the command couldn‘t execute.
puts "Creating directory..."
exec 'mkdir', 'new_directory'
# the code here and below will never be read
– gives you a good level of control
Takes the same parameters as
[env,] command [,options]
Optional hash with
:name => environment_name, e.g.
spawn(:name => 'development', 'echo hello world')
- A single string which is passed to the standard shell (with shell expansion), e.g.
exec('cat * | grep denied')
- The command name and one or more plain arguments (without shell expansion), e.g.
exec *[ 'git', 'add', 'Gemfile' ]
If the first command is a two-element array, the first element is taken as the command to be executed, and the second argument is used as the argv value, which may show up in process listings. E.g.
exec ['ls', 'foo'], 'foo.bar', 'baz.bar'
The shell used is
/bin/sh on Unix-like systems,
ENV["COMSPEC"] on Windows NT series, and similar.