Run

Definition
run(command, options={}, &block)
Module
Capistrano::Configuration::Actions::Invocation
File
capistrano/configuration/actions/invocation.rb

The run action is used to execute commands on one or more servers. It can be used to execute arbitrary shell commands, including any POSIX shell script syntax. It may also be given a block in order to capture output from and interact with the remote command.

The run command will execute the command on all matching servers simultaneously. People frequently want to know which server a command is being executed on at a particular moment--the answer is, honestly, "all of them." (If you want to try and do different things on different servers in parallel, check out the parallel helper.)

Arguments

command

This must be a string containing the shell command (or commands) to execute. It may be any valid POSIX shell command, including multiple commands combined using semicolons, pipes, or ampersands. No escaping of the input is performed.

If the command is determined to include a sudo invocation, run will also (by default) look for sudo prompts and, if found, will prompt the user for a password and pass what is entered back to the command.

Examples:

run "ln -s /usr/local/bin/ruby /usr/bin/ruby"
run "ls -l \"~/Project Folders\""
run "if [ -d /u/apps/social ]; then cd /u/apps/social && git pull; else cd /u/apps && git clone git://github.com/me/social.git; fi"
run "#{sudo} apachectl restart"

Note that if you embed the special string $CAPISTRANO:HOST$ anywhere inside of a command, it will be replaced with the host name of the server on which the command is being executed. In this way, you can tailor commands so that they work slightly differently for different hosts:

run "cp /u/apps/social/config/solr-$CAPISTRANO:HOST$.conf /u/apps/social/config/solr.conf"
run "/u/apps/social/script/init-$CAPISTRANO:HOST$.sh"

For changing the command per-host more significantly, see the parallel.

options

The options hash can be used to modify the default behavior of run. Recognized options are:

:hosts
Either a string (for a single target host) or an array of strings, indicating which hosts the command should run on. By default, the hosts are determined from current task's roles. This can also a Proc object, in which case it will be invoked and the return value used as the host list. (This can be useful for deferred calculation of the hosts to use, especially when passed as an option to task.)
:roles
Either a string or symbol (for a single target role) or an array of strings or symbols, indicating which roles the command should run on. If :hosts is specified, :roles will be ignored. By default, the roles are taken from the current task. This can also be a Proc object, in which case it will be invoked and the return value used as the roles list. (This can be useful for deferred calculation of the roles to use, especially when passed as an option to task.)
:only
Specifies a condition limiting which hosts will be selected to run the command. This should refer to values set in the role. For example, if a role is defined with :primary => true, then you could select only hosts with that setting by specifying :only => { :primary => true }.
:except
Specifies a condition limiting which hosts will be selected to run the command. This is the inverse of :only (hosts that do not match the condition will be selected).
:once
If true, only the first matching server will be selected. The default is false (all matching servers will be selected).
:max_hosts
Specifies the maximum number of hosts that should be selected at a time. If this value is less than the number of hosts that are selected to run, then the hosts will be run in groups of max_hosts. The default is nil, which indicates that there is no maximum host limit. Warning: this setting will probably be removed in a future release.
:shell
Says which shell should be used to invoke commands. This defaults to "sh", but you could use this to select (e.g.) "/bin/bash" if a bare "sh" doesn't work on your system for some reason. Setting this to false causes Capistrano to invoke the command directly, without going through a separate shell.
:data
If not nil (the default), this should be a string that will be passed to the command's stdin stream. This can be used to "prime the pump", if some command needs some initial interaction before doing something useful.
:pty
If true, a pseudo-tty will be allocated for each command. The default is false. Note that there are benefits and drawbacks both ways. Empirically, it appears that if a pty is allocated, most SSH server daemons will not read user shell start-up scripts (e.g. bashrc, etc.). However, if a pty is not allocated, some commands (like sudo, or git, or svn) will run in non-interactive mode and will not prompt for (e.g.) passwords. You have to choose your poison, apparently.
:env

&block

If no block is passed to run, run will default to echoing all output from the command. If you specify a block, however, you can capture and process the output from the command as the command emits it, and you can also send data back on the command's stdin stream.

The block takes three parameters:

run "command" do |channel, stream, data|
  # ...
end

The channel parameter is the SSH channel object that is hosting the command. This is used to send data back to the command, as well as to determine which server sent the data to you (since commands are run in parallel on all matching servers).

run "command" do |channel, stream, data|
  puts "host-name: " + channel[:host]        # server host name, as a string
  puts "server object: " + channel[:server]  # Capistrano::ServerDefinition object for the server
  channel.send_data("password\n")            # send data back via the remote command's stdin stream
end

The stream parameter is a symbol, either :out (for stdout) or :err (for stderr), indicating which output stream the data arrived on. You can use this to differentiate between streams, if you need to. For instance, if you know that any data from stderr means an error happened, you can act accordingly when stream is :err.

Lastly, the data parameter is a string containing the data emitted by the command. It is important to note that all of a command's output may not be sent in a single chunk. In fact, the data may not even be entirely line-wise. Thus, a single command may result in multiple invocations of the block, with each data chunk being the next block of data from the command.

This is further complicated by the fact that each server will use the same callback, so if you are invoking a command on three servers, each of those three command invocations will use the same block. If you need to interact with the remote commands, you can use channel[:host] and channel[:server] to determine which server sent the data.

See Also