Rex::Commands::Run(3)
π Rex::Commands::Run(3) β the manual page, but make it bestie β¨
okay so this is the Rex::Commands::Run(3) page from the User Contributed Perl Documentation, and it's literally all about running remote commands. it's giving "ssh but make it fashion". let's get into it π«Ά
πΈ NAME πΈ
Rex::Commands::Run β Execute a remote command π»β¨
π DESCRIPTION π
bestie. with this module you can run a command. that's it. that's the vibe. honestly iconic of it.
π¦ SYNOPSIS π¦
here's the whole mood in two lines, no cap:
my $output = run 'ls -l';
sudo 'id';
β CONFIGURATION AND ENVIRONMENT β
okay so real talk, lowkey important: Rex may set the PATH environment variable when it's executing commands on the user's behalf to a different value compared to when you'd execute the same commands manually. like, it just might. heads up π«Ά
the following are available to control the related behavior:
pathcommandset_pathconfiguration optionno_path_cleanupfeature flagsource_profilefeature flagsource_global_profilefeature 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. yes, that $?. the classic. π
run 'uptime';
my $output = run 'uptime';
my @output_lines = run 'uptime';
β οΈ note time bestie: when thettyfeature flag is enabled, the combined output containing bothSTDOUTandSTDERRis returned viaSTDOUT. when using theno_ttyfeature flag, or the 1.0 feature bundle (or newer), then run() returns only theSTDOUToutput 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, and honestly? obsessed with this list:
cwd => $pathβ sets the working directory of the executed command to$path. likecdbut make it remote πͺonly_if => $condition_commandβ executes the command only if$condition_commandreturns success. gatekeeping, but in a good way πunless => $condition_commandβ executes the command if$condition_commandreturns failure. the contrarian option, we love heronly_notified => TRUEβ queues the command to be executed later upon notification. it's not lazy, it's strategic πenv => { var1 => $value1, ..., varN => $valueN }β sets environment variables for the given command π±timeout => valueβ sets the timeout for the command to be run. hurry up, bestie β°auto_die => TRUEβ die if the command returns with an exit code indicating failure. can be set globally via theexec_autodiefeature flag πcommand => $command_to_runβ if present, Rex will execute$command_to_run, and treat the first arugment as an identifier for the givenrun()block (e.g. to be triggered with notify). (yes it says "arugment" in the original and i'm keeping it, it's part of the lore π)creates => $file_to_createβ tries to create$file_to_createupon execution, and skips execution if the file already exists. if it's already there, we simply do not βcontinuous_read => $callbackβ calls$callbacksubroutine 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$patternis detected in the command's output. we're leaving early, bye πββοΈ
π 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. very demure, very mindful of your quoting β¨
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. it's giving "on read, but for shell commands" π¬
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. first come, first served π
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. (perl said "i'm the main character here" and honestly? correct π)
depending on your remote sudo configuration, you may need to define a sudo password with sudo_password first:
sudo_password 'my_sudo_password'; # hardcoding
π hardcoding a password, bestie? i'm not judging. okay i'm judging a little. do what you gotta do.
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. so many options, so little time π«
you can turn sudo on globally with:
sudo TRUE; # run _everything_ with sudo
β οΈ yes. _everything_. the original said it with underscores so you know it's serious.
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',
};
π bug note energy: 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
π sign-off π
and that's the whole page, bestie! this was Rex::Commands::Run(3) from perl v5.42.3, dated 2023-08-05, brought to you by the User Contributed Perl Documentation girlies. go run some commands. slay. periodt π
β¨π¦
π¦ where this page comes from
- nixos 26.05: perl5.42.3-Rex 1.14.3
- nixpkgs unstable: perl5.42.3-Rex 1.14.3
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms