Replace your SSH loop script
From ControlTier
This page introduces the idea of command dispatching using ctl-exec as an alternative to SSH looping scripts.
Contents |
Scenario
You have a shell script that basically is an SSH loop around a set of remote hosts, where at each pass, you execute one or more commands. It has a structure something like this:
FORALL host in HOST-LIST SSH host command statement . . . END FORALL
Here's an example Bash script that executes the uname command across two hosts:
#!/bin/bash NODES="centos demo@development" for n in $NODES do ssh $n uname -a done
Issues
- Can't debug it on one of the remote nodes
- It mixes looping and ssh calls
- You have to edit your script anytime you need to change host targets. This is undesirable because it leads to a lot of one-off copies which end up being a burden to maintain.
- Often these are just a temporary solution so functionality, like error handling, are not implemented
Alternatives
Here are some alternatives that use ctl-exec.
Benefits:
- Less code complexity: Looping, node addressing, and individual steps separated.
- Flexibility: Use the node filtering options
- Error recovery: Use "-K" to skip over any node where the command fails
Single command
If you have just a single command statement, you can use ctl-exec like so:
ctl-exec -- uname -a
Scripts
You can have ctl-exec execute multiple commands in the form of a shell script.
Script file
You might prefer to save a series of command statements to a script file. The ctl-exec command will copy the script and execute it on each remote host:
File listing: info.sh
#!/bin/bash uname -a; who;
You can let ctl-exec copy that script to the target host and then run it:
ctl-exec -s info.sh
Stdin
The ctl-exec command can read the script statements from standard input.
You can specify the "-S" or "--stdin" option to have ctl-exec read from standard input.
Here's an example of the uname command being read from stdin:
$ echo "uname -a"|ctl-exec -S
You can also use the "here document" syntax:
ctl-exec -S <<EOS command statement 1; command statement 2; ... command statement N; EOS
Here's an example using the here document syntax:
ctl-exec -S <<EOS uname -a; who; EOS
| ||||||||||||||