Posted almost 4 years ago. Visible to the public. Repeats.

Execution of shell code in Ruby scripts

There are several ways to execute shell code in Ruby. Spawn is the method behing exec, system and %x[…], don’t use it, but check the documentation below.

#%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
  • nil if command execution fails, $? holds an error status.

Example:

result = system 'cp', '/full/path/to/my_file', '/target/directory' if result.nil? puts "Error was #{$?}" elsif result puts "You made it!" end

#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.

#open3 – for those who want to control everything “Open3 grants you access to stdin, stdout, stderr and a thread to wait the child process when running another program. You can specify various attributes, redirections, current directory, etc., of the program as Process.spawn.” Quoted from the docs

Use open3 when you have to explicitly manage all input, output, and errors.

Growing Rails Applications in Practice
Check out our new e-book:
Learn to structure large Ruby on Rails codebases with the tools you already know and love.

Author of this card:

Avatar
Dominik Schöler
Keywords:
command, line, parameters, arguments, cli
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code

License for source code

All source code included in the card Execution of shell code in Ruby scripts is licensed under the license stated below. This includes both code snippets embedded in the card text and code that is included as a file attachment. Excepted from this license are code snippets that are explicitely marked as citations from another source.

The MIT License (MIT)

Copyright (c) 2011-2014 makandra GmbH

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
Posted by Dominik Schöler to makandropedia