Skip to content

Run a Remote Script

Runs a shell command on one or more server resources, over whatever agent each server is configured to connect with. The command text, the arguments and the environment come from the form, and the return code plus the command output decide whether the job carries on or stops.

Use this when the work has to happen on the target machine. For anything that runs on the Clarive server itself, use Run command or local script, which is the same form minus the server picker and plus standard input and output files. To send a block of code rather than a command line, use Eval Remote. To move a file rather than run something, use Ship File Remotely.

Server host_one host_two inactive: skipped run command on each, in turn rc 0 rc not 0 scan the Output patterns, capture variables, write the FINISHED line Errors decides: fail, warn or silent output patterns are not scanned A failure on one server stops the run: later servers in the list never execute. Under Errors: custom a matching range takes the lower path, even for rc 0.

Fields

Server

The server resources to run on. Only resources that can hold an agent appear in the picker, and you can select more than one. The command runs on each in turn, on a fresh connection, in the order they appear in the box.

The field accepts ${var} entries as well as picked resources. A variable that expands to a comma-separated string is split, so one entry holding host_one,host_two targets two servers.

A server marked inactive logs Server <name> is inactive. Skipped and contributes nothing. The remaining servers still run.

An entry that does not name a resource ends the step with CI record not found for mid <entry>. That is what a ${var} carrying a stale value or a deleted resource looks like from the job log.

Leaving the picker empty is a silent no-op. Nothing executes, nothing is logged, and the op reports success. That is the usual explanation for a step that seems to have vanished from the job log.

User

The account to connect as. Left blank, the connection uses the user configured on the agent attached to the server resource. Fill it in only to override that for this step.

Some agent types turn the user into a switch-user wrapper around the command, others pass it as credentials at connection time. Either way the value also appears in the user@host prefix on the log lines.

Command

The command line to run. It goes to the remote shell as written, so command separators, pipes, redirections and globbing behave the way they do on that platform: cd /tmp && ./deploy.sh works, and so does foo | bar.

The text expands ${var} twice. First against the stash, then against the attributes of the server it is about to run on. The second pass is what makes ${hostname} and any custom parameter you added to the server resource usable here, and it happens separately per server, so one op can adapt itself to each target. A name that neither pass can resolve is left in the text literally as ${name}, so a typo reaches the remote shell verbatim instead of becoming an empty string.

If the whole field is exactly one placeholder and that variable holds a list, every element runs as its own command, one after another, on the same connection. Execution does not stop at the first failure: all of them run, the outputs are concatenated, and the highest return code seen is the one reported. Arguments is ignored entirely in that case, and the step closes with one FINISHED remote script line per element rather than one for the whole list.

Arguments

A grid of arguments appended to the command, one per row. Add appends a row prefilled with ., Delete removes the selected row, and a single click on a row edits it. Each row expands ${var} under the same two-pass rule as the command.

Arguments here and arguments written into the command line do not mix. Put everything in Command, or put the program in Command and each argument in its own row.

Environment

A grid of environment variables to set for the command, one NAME=value entry per row.

This only reaches the remote process on Clax agents. Servers connected over SSH discard the list without a warning, so a command that depends on a variable set here runs with it unset. On an SSH-connected server, set it inside the command text instead: FOO=bar ./script.sh.

Home Directory

The directory to change into before running. A similar limitation applies: Clax, Balix and worker agents honour it, SSH-connected servers ignore it and the command runs wherever the login lands. cd /some/path && ... in the command text is the portable version.

Left blank, no directory change is attempted.

Log Display

Replaces the command text in the STARTING remote script and FINISHED remote script headline entries. Set it when the command line carries a password or is too long to read in the monitor.

This masks the headline only. The detail attached to those entries still carries the full configuration of the step, including the real command line and every other field on this form. Treat it as a readability feature and not as a secret-hiding one. Credentials belong in server resource attributes or in variables.

Left blank, the headline shows the command followed by its arguments.

Errors

How the return code is treated. The default is fail.

Errors A non-zero return code
fail logs an error and stops the job
warn logs a warning and carries on
custom is looked up in the Return Codes ranges below
silent is recorded at debug level only

fail is the only setting that stops the job. Under warn and silent the step counts as finished and the next op runs, so a failed deployment looks like a completed one unless a later op checks something.

warn and silent still close the step with a FINISHED remote script line, tagged warnings detected or silent errors detected. Under fail the job stops before that line is written, so the absence of a FINISHED line is the fastest way to spot which server died.

Return Codes

Three text boxes, shown only when Errors is set to custom.

Ok, Warn and Error each take a set of return codes as a comma-separated list of numbers and ranges: 0, 2,4,8, 4-8 for the inclusive span, 8- for eight and above, -3 for three and below. Comparison is numeric.

The three are evaluated as Warn, then Error, then Ok, and the last match wins. Ok therefore overrides the other two, which is how you declare that a tool's exit code 1 means "nothing to do". Putting 0 in Error makes a successful command fail the job, which is occasionally what you want.

A code matched by Ok is not treated as a clean run. It takes the same path a warning would, logged at debug level and closed with a FINISHED remote script line tagged silent errors detected, and the Output patterns below are not scanned. Put 0 in Ok and that applies to every successful run of the step, which quietly disables output scanning across the board.

A non-zero return code that matches none of the three ranges is swallowed. No log entry, no failure, no FINISHED line, and the output patterns below are skipped. If you use custom, cover the whole range: give Error a catch-all such as 1- and then carve out the codes you tolerate in Ok.

Output

Four tabs of regular expressions matched against the combined standard output and standard error of the command. Each tab is a grid with Add and Delete. New rows arrive prefilled with .*, which matches everything, so a forgotten empty row on the Error tab fails every run.

Tab Effect when a pattern matches
Error logs an error entry with the full output attached, and stops the job when Errors is fail
Warn logs a warning entry with the full output attached
OK logs a note and stops any Error match from failing the job
Capture logs nothing of its own and exists to pull values into the stash

Patterns are plain regular expressions. To add flags, write the pattern as !!pattern!!i, where the trailing letters are the usual regular expression flags.

The OK tab is scanned first and stops at its first match. Error and Warn then run every pattern in their grid, so several can match and each produces its own entry. What an OK match cancels is narrow: the job no longer stops, but every Error pattern is still tested and each match still writes its error entry to the log with the output attached. A non-zero return code is still a non-zero return code as well.

None of these tabs are consulted when the return code already triggered the error path. That is the usual reason a Capture pattern produces nothing: the command failed, so its output was never scanned.

Named captures

A named group in any of the four tabs writes a stash variable. A pattern of version=(?<build_version>\S+) leaves build_version in the stash for later ops to read, and a debug entry records what was captured.

Only one pattern's captures survive. The tabs are scanned as OK, Error, Warn, Capture, and each pattern that matches replaces the whole set left by the previous one, including replacing it with nothing when the matching pattern has no named groups. Keep your named groups on a single pattern and put it on the Capture tab, which is scanned last.

What the step returns

Set a Return Key in the op properties panel to keep the result. For a single server you get a value with three entries: output holds the combined output text, rc holds the return code and ret holds whatever extra the agent reported, which differs per agent type and is often empty. Read them as ${myresult.rc}. With several servers you get one such value per server, in picker order.

A Return Key of = merges the entries into the stash at the top level instead, so a single-server run leaves ${output}, ${rc} and ${ret} directly. Those are short, common names; prefer a key of your own unless you consume them in the very next op.

Rollback and timeout

Two settings in the op properties panel change how this op behaves, and neither is on the config form.

Needs Rollback? marks the step as needing to be replayed if the job later turns around. Rollback Needed Before marks it as soon as the connection is made, Rollback Needed After only once a server has finished without error. See rollback.

Timeout caps the run in seconds. Left at zero, SSH-connected servers still cut the command off after 60 seconds and report it as an agent error, which surprises people running long builds. Set an explicit timeout for anything slow.

Combining with other ops

Put Ship File Remotely before this op to place the script you are about to run, or Write remote file for something short you can generate inline. Use Retrieve a remote file afterwards to bring a log or an artifact back, then Publish local file to log to attach it to the job.

Wrap the op in TRY statement with CATCH statement when a failure needs handling rather than stopping the job, or in RETRY for a step that fails intermittently.

Branch on a captured value with IF var condition THEN, which reads the stash variables your named captures wrote.

Examples

Run a build on a single server and let a known-harmless exit code through.

Server            build_host
Command           cd /opt/build && make release
Errors            custom
Return Codes      Ok: 0,2    Warn:      Error: 1,3-

Deploy to every node in a list held in the stash, mask the command in the log, and pull the deployed version back out of the output.

Server            ${prod_nodes}
User              appuser
Command           /opt/app/deploy.sh --token ${deploy_token}
Log Display       deploy application to ${hostname}
Errors            fail
Output > Capture  deployed version (?<deployed_version>[\d.]+)

Run a check that reports problems in its text rather than in its return code.

Server            db_host
Command           /usr/local/bin/healthcheck --all
Errors            fail
Output > Error    ^FATAL:
Output > Warn     !!degraded!!i
Output > OK       ^ALL CHECKS PASSED$