---
name: "Rex::Commands::Run"
section: "3pm"
platform: "linux"
package: "rex"
version: "1.16.0-1"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/Rex::Commands::Run"
---

# Rex::Commands::Run(3pm)

Execute a remote command

## NAME

Rex::Commands::Run - Execute a remote command

## DESCRIPTION

With this module you can run a command.

## SYNOPSIS

```
 my $output = run 'ls -l';
 sudo 'id';
```

## CONFIGURATION AND ENVIRONMENT

Please note that Rex may set the `"PATH"` environment variable when executing commands on the user's behalf to a different value compared to executing the same commands manually. The following are available to control the related behavior:

- path command

  - set\_path configuration option

  - no\_path\_cleanup feature flag

  - source\_profile feature flag

  - source\_global\_profile feature flag

  ## EXPORTED FUNCTIONS

### run($command \[, $callback\], %options)

This function will execute the given `$command` and returns the output. In scalar context it returns the raw output as is, and in list context it returns the list of output lines. The exit value of the command is stored in the `$?` variable.

```
 run 'uptime';
 my $output       = run 'uptime';
 my @output_lines = run 'uptime';
```

Please note when the `"tty"` feature flag is enabled the combined output containing both `"STDOUT"` and `"STDERR"` is returned via `"STDOUT"`. When using the `"no_tty"` feature flag, or the `1.0` feature bundle (or newer), then `run()` returns only the `"STDOUT"` output of the command.

To access separate `"STDOUT"` and `"STDERR"` output, use a callback subroutine, for example:

```
 run 'uptime', sub {
   my ( $stdout, $stderr ) = @_;
   my $server = Rex::get_current_connection()->{server};
   say "[$server] $stdout\n";
 };
```

It also takes further options in a form of a hash. Supported options are:

- cwd =\> $path

  Sets the working directory of the executed command to `$path`.

- only\_if =\> $condition\_command

  Executes the command only if `$condition_command` returns success.

- unless =\> $condition\_command

  Executes the command if `$condition_command` returns failure.

- only\_notified =\> TRUE

  Queues the command to be executed later upon notification.

- env =\> { var1 =\> $value1, ..., varN =\> $valueN }

  Sets environment variables for the given command.

- timeout =\> value

  Sets the timeout for the command to be run.

- auto\_die =\> TRUE

  Die if the command returns with an exit code indicating failure. It can be set globally via the exec\_autodie feature flag.

- command =\> $command\_to\_run

  If present, Rex will execute `$command_to_run`, and treat the first argument as an identifier for the given `run()` block (e.g. to be triggered with notify).

- creates =\> $file\_to\_create

  Tries to create `$file_to_create` upon execution, and skips execution if the file already exists.

- continuous\_read =\> $callback

  Calls `$callback` subroutine reference for each line of the command's output, passing the line as an argument.

- end\_if\_matched =\> qr{$pattern}

  End execution early as soon as `$pattern` is detected in the command's output.

Examples:

If you only want to run a command if another command succeeds or fails, use the `"only_if"` or `"unless"` options.

```
 run 'some-command',
   only_if => 'pgrep httpd'; # only run if httpd is running
 run 'some-other-command',
   unless => 'pgrep httpd'; # only run if httpd is _not_ running
```

If you want to set custom environment variables you can do it like this:

```
 run 'my_command',
   env => {
     env_var_1 => 'the value for 1',
     env_var_2 => 'the value for 2',
   };
```

If you want to end the command upon receiving a certain output:

```
 run 'my_command',
   end_if_matched => qr{$pattern};
```

### run($command, $arguments, %options)

This form will execute `$command` with the given `$arguments` pass as an array reference. All arguments will be quoted by Rex with `"Net::OpenSSH::ShellQuoter->quoter()"` according to the managed host's shell.

```
 run 'ls', [ '-l', '-t', '-r', '-a' ];
 run 'ls', [ '/tmp', '-l' ], auto_die => TRUE;
```

### run($command\_description, command =\> $command, %options)

If you only want to run a command in certain cases, you can queue the command and notify it to trigger its execution.

```
 run 'extract-something',
   command       => 'tar -C /foo -xzf /tmp/foo.tgz',
   only_notified => TRUE;
 # some code ...
 notify 'run', 'extract-something'; # now the command gets executed
```

### can\_run($command)

This function checks if a command is available in the path. It accepts a list of commands, and returns the full path to the first command found.

```
 task 'uptime', sub {
   if ( my $cmd = can_run( 'uptime', 'downtime' ) ) {
     say run $cmd;
   }
 };
```

### sudo

Run a single command, a code block, or all commands with `"sudo"`. You need perl to be available on the remote systems to use `"sudo"`.

Depending on your remote sudo configuration, you may need to define a sudo password with *sudo\_password* first:

```
 sudo_password 'my_sudo_password'; # hardcoding
```

Or alternatively, since Rexfile is plain perl, you can read the password from terminal at the start:

```
 use Term::ReadKey;
 print 'I need sudo password: ';
 ReadMode('noecho');
 sudo_password ReadLine(0);
 ReadMode('restore');
```

Similarly, it is also possible to read it from a secret file, database, etc.

You can turn sudo on globally with:

```
 sudo TRUE; # run _everything_ with sudo
```

To run only a specific command with sudo, use :

```
 say sudo 'id';                # passing a remote command directly
 say sudo { command => 'id' }; # passing anonymous hashref
 say sudo { command => 'id', user => 'different' }; # run a single command with sudo as different user
```

To run multiple commands with `"sudo"`, either use an anonymous code reference directly:

```
 sudo sub {
     service 'nginx' => 'restart';
     say run 'id';
 };
```

or pass it via `"command"` (optionally along a different user):

```
 sudo {
     command => sub {
         say run 'id';
         say run 'pwd', cwd => '/home/different';
     },
     user => 'different',
 };
```

**Note** that some users receive the error `"sudo: sorry, you must have a tty` `to run sudo"`. In this case you have to disable `"requiretty"` for this user. You can do this in your sudoers file with the following code:

```
   Defaults:$username !requiretty
```
