[AMG]: As its name implies, '''multissh''' [ssh]'es to multiple hosts for the purpose of executing commands. This all by itself is a very trivial task, but the fun begins when you start to consider what to do with '''stdin''', '''stdout''', and '''stderr'''. '''multissh''' takes all input received on '''stdin''' and sends it to all remote hosts; all '''stdout''' and '''stderr''' text from the remote hosts is piped to the local '''stdout''' and '''stderr''', with the hostname prepended. New in version 0.2, '''multissh''' is also a Tcl package, consisting of a single command. I want you to guess what that command is named. As a package '''multissh''' is quite limited: basically if you're writing a Tcl script using '''multissh''', you can call it as a command rather than [[[exec]]]'ing it, and that's all. The script can't supply input (besides the command line) and can't see the output or error messages. But if there is interest, '''multissh''' can be made much nicer. ---- Perhaps an example will help. Here's a "screenshot": [root@utanium|~]# multissh "localhost bravo charlie" uptime localhost: 17:51:49 up 4:52, 2 users, load average: 0.00, 0.00, 0.00 bravo: 17:50:52 up 2:29, 1 user, load average: 0.00, 0.00, 0.00 charlie: 17:51:05 up 2:27, 1 user, load average: 0.00, 0.00, 0.00 [root@utanium|~]# Well, there you have it. Now for '''stdin''' handling: [root@utanium|~]# multissh "localhost bravo charlie" "cat > file" illustrative verbiage ^D [root@utanium|~]# multissh "localhost bravo charlie" "cat < file" localhost: illustrative verbiage bravo: illustrative verbiage charlie: illustrative verbiage [root@utanium|~]# multissh "localhost bravo charlie" "rm file" [root@utanium|~]# Amazing, really. '''stderr''' works too: [root@utanium|~]# multissh "localhost bravo charlie" "rm file" localhost: rm: cannot remove `file': No such file or directory charlie: rm: cannot remove `file': No such file or directory bravo: rm: cannot remove `file': No such file or directory [root@utanium|~]# Although not very well. :^) I don't get access to '''stderr''' until I [[[close]]] the [ssh] channels, so all error messages are delayed until the session is closed. There's a related problem. Some programs, for example '''sort''', generate output after getting EOF on '''stdin'''. But Tcl doesn't support closing a child process channel's '''stdin''' and continuing to listen to its '''stdout'''/'''stderr''', so it can never see any output that happens after '''stdin''' EOF. That's bad. On the other hand, if I didn't tell you about this problem, you'd probably never notice it--- how often do you run '''sort''' on remote hosts, anyway? Just be wary for the time being, and maybe someday this will be fixed. ---- Here's the TODO/ideas list. If you have any comments or implementation tips, write them here or email them to me ([Andy Goth]). * Continue investigation of closing only '''stdin''' and leaving '''stdout'''/'''stderr''' open. * Continue investigation of getting '''stderr''' text without closing the channel. * Double-check that the standalone/sourced test is correct. * Make reentrant by eliminating globals or creating "instances". * Allow the caller to supply handlers for various events. * Convert the [[[puts]]]s into default event handlers. * Allow the caller to supply an alternate source for '''stdin''' data. * Optionally return immediately and expose [[node_wait]] in some form. * Be more configurable in general. * Write a GUI frontend. And another thing... Lately I have written several tools that all need to be callable both from Tcl and the shell using more or less the same interface. I'm considering factoring out the common code into a package. Basically such a package would need to handle detecting whether the code was executed or sourced, outputting through '''stdout'''/'''stderr''' versus [[[return]]]/[[[error]]], and generating shell-style or Tcl-style lists. Is anyone interested? I don't think it's very much code, but I have it duplicated in a lot of places. [AMG], update: Tcl 8.6 makes it possible to do several of the most important things on my TODO list. In particular, I can separately close stdin and stdout by means of [TIP] #332 "Half-Close for Bidirectional Channels" [http://tip.tcl.tk/332]. Also I can use TIP #304 "A Standalone [chan pipe] Primitive for Advanced Child IPC" to access stderr as it gets generated. ---- What: multissh Where: http://andy.junkdrome.org/devel/multissh/ Description: Program/package for simultaneously executing commands on multiple remote hosts. Version: 0.2 Updated: 27 October 2005 License: GPL 2.0 or later Contact: Andy Goth <> Application | Package