Execution of shell code in Ruby scripts

Deprecated ways to execute shell code in Ruby

This is just a reference for legacy code. For new code, always use capture3.

%x{ } 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.

Example:
^
name = 'ls'
result = which #{name}

It does not escape anything you inject in the string.

If you want to find out if the call was successful you can ask $?.success?.

system – when you want to know how it went

Similar to exec, but executes the given command in a subshell. Your script will go on. Returns:

  • true if the command gives zero exit status
  • false for non zero exit status

Example:
^
if system 'cp', '/full/path/to/my_file', '/target/directory'
puts "You made it!"
else
puts "Something went wrong"
end

Note that system (as well as exec) has two distinct argument patterns:

  1. a single string argument is passed to the shell like "Hey, lets pretend the user typed this. Please run it!"

    >> system 'echo *'
    

    This is equivalent to:

    $ 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:

    file1 file2 file3
    
  2. 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:

    system 'echo', '*'
    

    This is equivalent to:

    $ /bin/echo '*'
    

    Since Ruby is passing all arguments as Strings, there will be no wildcard expansion or the like.

    Output will be:

    *
    

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 $PATH.

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.

exec – 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 stdout.

Raises SystemCallError if the command couldn‘t execute.

Example:
^
puts "Creating directory..."
exec 'mkdir', 'new_directory'
# the code here and below will never be read

spawn – gives you a good level of control

Takes the same parameters as exec and system: [env,] command [,options]

env

Optional hash with :name => environment_name, e.g. spawn(:name => 'development', 'echo hello world')

command, either:

  • 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[0] value, which may show up in process listings. E.g. exec ['ls', 'foo'], 'foo.bar', 'baz.bar'

options

see the Ruby docs

The shell used is /bin/sh on Unix-like systems, ENV["RUBYSHELL"] or ENV["COMSPEC"] on Windows NT series, and similar.

Spawn calls IO.popen.

Dominik Schöler about 10 years ago
This website uses short-lived cookies to improve usability.
Accept or learn more