forked from LubyRuffy/fofa
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpssh.rb
More file actions
executable file
·140 lines (117 loc) · 3.72 KB
/
pssh.rb
File metadata and controls
executable file
·140 lines (117 loc) · 3.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env ruby
require 'sshkit'
require 'sshkit/dsl'
require 'optparse'
require 'ostruct'
require 'yaml'
Version = '0.1'
class OptparseExample
#
# Return a structure describing the options.
#
def self.parse(args)
# The options specified on the command line will be collected in *options*.
# We set default values here.
options = OpenStruct.new
options.verbose = false
options.username = ENV['USERNAME'] || `whoami`.split(/[\r\n]/)[0]
options.password = nil
options.mode = :sequence
options.display_results = true
options.servers = []
opt_parser = OptionParser.new do |opts|
opts.banner = "Usage: #{__FILE__} [options] cmdline"
opts.separator ""
opts.separator "Specific options:"
# Mandatory argument.
opts.on("-u", "--username USERNAME",
"Username to ssh loginm, default is current user") do |username|
options.username = username
end
opts.on("-p", "--password PASSWORD",
"Password to ssh login") do |password|
options.password = password
end
opts.on("-h", "--hosts HOSTS_FILE_PATH",
"Each line is a host, could be '1.1.1.1' or 'user@a.com'") do |hostfile|
options.servers = File.readlines(hostfile).map{|l| l.strip }.select{|l| l.size>2 && !l.include?('#')}
end
opts.on("-y", "--ymlhosts HOSTS_FILE_PATH,GROUPKEY",
"Each line is a host group, could be 'group1=1.1.1.1,2.2.2.2'") do |hostfile|
file,group = hostfile.split(',')
unless group
puts "[Error]: please specify group of server!"
exit
end
config = YAML::load(File.open(file))
unless config[group]
puts "[Error]: can not find group of server!"
exit
end
options.servers = config[group].split(',')
end
opts.on("-m", "--mode MODE",
"Could be : sequence, parallel, groups, default is sequence") do |mode|
options.mode = mode.to_sym
end
opts.on("-n", "--no-display",
"Do not display results of command execution") do
options.display_results = false
end
opts.separator ""
opts.separator "Common options:"
# No argument, shows at tail. This will print an options summary.
# Try it and see!
opts.on_tail("--help", "Show this message") do
puts opts
exit
end
# Another typical switch to print the version.
opts.on_tail("--version", "Show version") do
puts ::Version.join('.')
exit
end
end
opt_parser.parse!(args)
options
end # parse()
end # class OptparseExample
options = OptparseExample.parse(ARGV)
unless options.servers.size>0
puts "ERROR: no server to execute!"
puts options
exit
end
unless ARGV.size>0
puts "ERROR: no command to execute!"
puts options
exit
end
#SSHKit.config.default_env = { path: '/usr/local/bin:$PATH' }
#SSHKit.config.format = :dot
servers = options.servers.collect do |s|
user_host = s
user_host = "#{options.username}@#{user_host}" if options.username && !s.include?('@')
h = SSHKit::Host.new(user_host)
h.password = options.password if options.password
h
end
info = "execute #{ARGV} as #{options.username} at #{options.servers.size} servers, mode is : #{options.mode}"
puts info
commands = ARGV
#commands = ARGV[0].split(' ') if ARGV.size==1
on servers, in: options.mode do |s|
#begin
if options.display_results
#puts "=====#{s}=====",capture( commands )
puts "=====#{s}=====",capture( commands[0], commands[1..-1] )
else
execute(commands[0], commands[1..-1])
#execute(commands)
end
#rescue SSHKit::Runner::ExecuteError => e
# puts e
#rescue => e
# puts e
#end
end