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