2017-12-20
The Advent of Void: Day 20: shmux
When you have multiple machines, sometimes you’ll want to run the same
commands on all of them. There are many tools for this job, starting
from simple for
loops on the shell to full-fledged configuration
management systems such as Puppet or Chef.
A good compromise is shmux(1), the shell multiplexer.
For example, we can measure the uptimes of my servers,
passing the command with -c
:
% shmux -c uptime vuxu.org root@epona.vuxu.org hecate.home.vuxu.org
vuxu.org: 15:48:01 up 91 days, 6:05, 45 users, load average: 0.55, 0.47, 0.40
root@epona.vuxu.org: 15:48:07 up 502 days, 19:29, 1 user, load average: 0.37, 0.29, 0.29
hecate.home.vuxu.org: 15:48:03 up 225 days, 5:51, 2 users, load average: 0.06, 0.03, 0.05
3 targets processed in 2 seconds.
Summary: 3 successes
shmux is quite clever about this, e.g. if we do a mistake and the command fails, it stops and asks us what to do:
shmux -c oopstime localhost vuxu.org root@epona.vuxu.org hecate.home.vuxu.org
localhost! zsh:1: command not found: oopstime
shmux! Child for localhost exited with status 127
-- [PAUSED], 3 Pending/0 Failed/1 Done -- [1.7, 1.8]
?
>> Available commands:
>> q - Quit gracefully
>> Q - Quit immediately
>> <space> - Pause (e.g. Do not spawn any more children)
>> 1 - Spawn one command, and pause if unsuccessful
>> <enter> - Keep spawning commands until one fails
>> + - Always spawn more commands, even if some fail
>> F - Toggle failure mode to "quit"
>> S - Show current spawn strategy
>> p - Show pending targets
>> r - Show running targets
>> f - Show failed targets
>> e - Show targets with errors
>> s - Show successful targets
>> a - Show status of all targets
>> k - Kill a target
a
>> [0] error: localhost
>> [1] pending: vuxu.org
>> [2] pending: root@epona.vuxu.org
>> [3] pending: hecate.home.vuxu.org
Q
1 target processed (out of 4) in 89 seconds.
Summary: 3 unprocessed, 1 error
Error : localhost
Commands can be spawned in parallel when using -M max
.
By default, shmux spawns the first command on its own, to check it early.
Let’s say we want to keep the outputs, so we use -o
:
% shmux -M10 -o uptimes -c uptime localhost vuxu.org root@epona.vuxu.org hecate.home.vuxu.org
...
% ls uptimes
hecate.home.vuxu.org.exit 'root@epona.vuxu.org.exit'
hecate.home.vuxu.org.stderr 'root@epona.vuxu.org.stderr'
hecate.home.vuxu.org.stdout 'root@epona.vuxu.org.stdout'
localhost.exit vuxu.org.exit
localhost.stderr vuxu.org.stderr
localhost.stdout vuxu.org.stdout
Finally, the -a
and -A
options can be used to define
analyzers for the outputs, so see if everything worked fine.
% shmux -o uptimes -a regex -A up -c uptime ...
shmux is a useful tool for adhoc command execution as it requires no configuration and has sensible defaults.