aboutsummaryrefslogtreecommitdiff
path: root/rex
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2015-08-14 17:28:41 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2015-08-14 17:28:41 +0300
commitabd63950f8c76292e4f9a6868515ec7437ba279f (patch)
tree531a46ac321c5df38e8ef13bd304b961d984191d /rex
parent50c1f14c67cfb18d64e3244ada10faef603367fa (diff)
downloadrex-abd63950f8c76292e4f9a6868515ec7437ba279f.tar.gz
rex-abd63950f8c76292e4f9a6868515ec7437ba279f.tar.bz2
New option -b (--buffer-output).
Useful together with -j to prevent intermixing of output lines received from different servers.
Diffstat (limited to 'rex')
-rwxr-xr-xrex133
1 files changed, 82 insertions, 51 deletions
diff --git a/rex b/rex
index a428a13..6d13cb6 100755
--- a/rex
+++ b/rex
@@ -274,36 +274,34 @@ proc prusage {} {
puts ""
puts {OPTIONS are:
- -C, --config FILE read config from FILE
- -c, --cp, --copy copy arguments to each host (see the 2nd form above)
- -f, --copy-from copy arguments from the given host (3rd form)
- -d, --debug increase debugging level
- -E, --editdb [FILE]
- edit the database file (default ~/.rex/db)
- -e, --encrypt [WORD]
- encrypt the WORD (read it from the stdin if not supplied),
- and print out the result
- -g, --group NAME select host group
- -H, --host NAME add host to the list
- -i, --interactive interactively ask for missing usernames and passwords
- -j, --jobs N allow N jobs at once
- --list-groups list available host groups
- -l, --log log everything to the standard output
- --no-host-header don't print hostname before output from the host
- -N, --noop ignore all commands (useful for side effects)
- -P, --prefix prefix each output line with the server name or IP
- -p, --password PWD
- set password (unsafe!)
- -S, --script COMMAND is a script, copy it to each host prior to
- executing
- -s NAME read .rex/$NAME.rex in addition to the config file
- -u, --user NAME log in as user NAME
- -x, --program SCRIPT
- run expect SCRIPT after executing command on each host
- -w, --confirm prompt and wait for confirmation before each host
-
- -V, --version print program version and copyright statement
- -h, --help show this help list
+ -b, --buffer-output buffer output from servers
+ -C, --config FILE read config from FILE
+ -c, --cp, --copy copy arguments to each host (see the 2nd form above)
+ -f, --copy-from copy arguments from the given host (3rd form)
+ -d, --debug increase debugging level
+ -E, --editdb [FILE] edit the database file (default ~/.rex/db)
+ -e, --encrypt [WORD] encrypt the WORD (read it from the stdin if not
+ supplied), and print out the result
+ -g, --group NAME select host group
+ -H, --host NAME add host to the list
+ -i, --interactive interactively ask for missing usernames and passwords
+ -j, --jobs N allow N jobs at once
+ --list-groups list available host groups
+ -l, --log log everything to the standard output
+ --no-host-header don't print hostname before output from the host
+ -N, --noop ignore all commands (useful for side effects)
+ -P, --prefix prefix each output line with the server name or IP
+ -p, --password PWD set password (unsafe!)
+ -S, --script COMMAND is a script, copy it to each host prior to
+ executing
+ -s NAME read .rex/$NAME.rex in addition to the config file
+ -u, --user NAME log in as user NAME
+ -x, --program SCRIPT run the expect SCRIPT after executing command on each
+ host
+ -w, --confirm prompt and wait for confirmation before each host
+
+ -V, --version print program version and copyright statement
+ -h, --help show this help list
Report bugs to <gray+rex@gnu.org.ua>
}
@@ -868,6 +866,8 @@ proc runcp {args} {
set retry_count 0
set cmd_stub [lrange $args 1 end-1]
+ debug 2 "copying: \"$cmd_stub\" to $hosts"
+
foreach host $hosts {
set cmd $cmd_stub
lappend cmd [hostuser $host]@$host:[lindex $args end]
@@ -878,8 +878,6 @@ proc runcp {args} {
set sidinfo($spawn_id,state) INIT
}
- debug 2 "copying: $cmd"
-
while {[llength $sidlist] > 0} {
expect {
denied {
@@ -1012,7 +1010,8 @@ proc moresid {s state} {
proc runcmd {hosts command} {
global config
-
+ global reply
+
debug 2 "running $command on $hosts"
if { [info exists config(silent)] } {
@@ -1021,10 +1020,13 @@ proc runcmd {hosts command} {
set silent 0
}
log_user [config_option log]
-
- # if {!$silent && ![config_option no_host_header]} {
- # puts "$host:"
- # }
+
+ if {[llength $hosts] == 1 &&\
+ !$silent &&\
+ ![config_option no_host_header] &&\
+ ![config_option buffer_output]} {
+ puts "[lindex $hosts 0]:"
+ }
foreach host $hosts {
spawn -noecho ssh [hostuser $host]@$host
@@ -1104,15 +1106,21 @@ proc runcmd {hosts command} {
-i $sidlist
-re {^[^\n]*\n} {
+ if $silent {
+ continue;
+ }
set sid $expect_out(spawn_id)
if {$sidinfo($sid,state) != "LOGOUT"} {
set host $sidinfo($sid,host)
- if {!$silent} {
+ set text [regsub -all {\r} $expect_out(0,string) {}]
+ if [config_option buffer_output] {
+ lappend output($host) $text
+ } else {
if [config_option prefix] {
puts -nonewline "$host> "
}
- puts -nonewline [regsub -all {\r} $expect_out(0,string) {}]
+ puts -nonewline $text
}
}
}
@@ -1122,7 +1130,7 @@ proc runcmd {hosts command} {
send -i $sid "logout\r"
set sidinfo($sid,state) LOGOUT
}
-
+
timeout {
set sid $expect_out(spawn_id)
set host $sidinfo($sid,host)
@@ -1140,13 +1148,27 @@ proc runcmd {hosts command} {
}
}
debug 2 "finished $command on $hosts"
+ if [config_option buffer_output] {
+ foreach host $hosts {
+ if ![config_option no_host_header] {
+ puts "$host:"
+ }
+ foreach text $output($host) {
+ if [config_option prefix] {
+ puts -nonewline "$host> "
+ }
+ puts -nonewline $text
+ }
+ }
+ }
}
# #######################################################################
# The game begins...
# #######################################################################
-set shortopts "CcdeEfij:g:HhlNPp:Ssu:x:Vw"
+set shortopts "bCcdeEfij:g:HhlNPp:Ssu:x:Vw"
set longopts {
+ buffer-output b
config C
confirm w
copy c
@@ -1180,6 +1202,7 @@ set opterr 1
getopt -progname $argv0 -longopts $longopts $argc $argv $shortopts {
global optchar optarg config
switch -- $optchar {
+ b { set config(option,buffer_output) 1 }
d { incr config(debug) }
H { lappend config(hosts) $optarg }
e { set config(option,encrypt) 1 }
@@ -1448,8 +1471,13 @@ if {![info exists config(user)]} {
debug 1 "assuming user $config(user)"
}
-if {![config_option copy] &&
- [regexp {shell[ \t][ \t]*(.*)} "$config(command)" dummy host]} {
+if [config_option copy] {
+ debug 1 "copying $config(command)"
+ if {$config(sudo)!=""} {
+ debug 1 "... in sudo mode"
+ }
+ debug 1 "... to $config(hosts)"
+} elseif {[regexp {shell[ \t][ \t]*(.*)} "$config(command)" dummy host]} {
global config
debug 2 "entering shell mode"
set password_sent 0
@@ -1498,21 +1526,24 @@ if {![config_option copy] &&
}
debug 2 "quitting"
exit 0
-}
-
-debug 1 "running $config(command)"
-if {$config(sudo)!=""} {
- debug 1 "... in sudo mode"
+} else {
+ debug 1 "running $config(command)"
+ if {$config(sudo)!=""} {
+ debug 1 "... in sudo mode"
+ }
+ debug 1 "... on $config(hosts)"
}
-debug 1 "... on $config(hosts)"
if [info exists config(prologue)] {
debug 2 "running prologue script"
eval $config(prologue)
}
-if {$config(option,jobs) > 1} {
- set config(option,prefix) 1
+if {[config_option jobs] > 1} {
+ if ![config_option buffer_output] {
+ set config(option,prefix) 1
+ set config(option,no_host_header) 1
+ }
}
debug 2 "entering main loop"

Return to:

Send suggestions and report system problems to the System administrator.