Class: Cute::Bash::Bash
- Inherits:
-
Object
- Object
- Cute::Bash::Bash
- Defined in:
- lib/cute/bash.rb
Instance Method Summary collapse
- #_escape(args) ⇒ Object
- #_extend(path, suffix) ⇒ Object
- #_loop ⇒ Object
- #_nonce ⇒ Object
- #_run(cmd, _opts) ⇒ Object
- #_run_block(cmd, _opts) ⇒ Object
- #_unlines(s) ⇒ Object
- #abspath(path) ⇒ Object
- #append_line(path, line) ⇒ Object
- #append_lines(path, lines) ⇒ Object
- #aptget(*args) ⇒ Object
-
#assert(condition, msg = 'Assertion error') ⇒ Object
TESTING METHODS.
- #bc(text) ⇒ Object
- #build ⇒ Object
- #build_tarball(tarball, path) ⇒ Object
- #cd(path) ⇒ Object
- #contents(name) ⇒ Object (also: #cat)
- #cp(a, b) ⇒ Object
- #dirs(ignore = true) ⇒ Object
- #distribute(path, dest, *nodes) ⇒ Object
- #echo(text) ⇒ Object
- #exists(path) ⇒ Object
- #expand_path(path) ⇒ Object
-
#export(name, value) ⇒ Object
PUBLIC METHODS.
- #files(ignore = true, type = 'f') ⇒ Object
- #get_type(name) ⇒ Object
- #glob(pattern) ⇒ Object
- #hostname ⇒ Object
-
#initialize(stdin, stdout, debug = false) ⇒ Bash
constructor
A new instance of Bash.
- #join(*args) ⇒ Object
- #ls ⇒ Object
- #make_dirs(path) ⇒ Object
- #mkdir(path) ⇒ Object
- #mpirun(machines, params) ⇒ Object
- #mv(a, b) ⇒ Object
- #packages ⇒ Object
- #parse(&block) ⇒ Object
- #pwd ⇒ Object
- #remove_dirs(path) ⇒ Object
- #rm(*args) ⇒ Object
- #run(cmd, opts = {}) ⇒ Object
- #run_status(cmd, opts = {}) ⇒ Object
- #save_machines(machines, path = nil) ⇒ Object
- #tmp_file ⇒ Object
- #touch(path) ⇒ Object
- #untar(name, where = nil) ⇒ Object
- #which(prog) ⇒ Object
Constructor Details
#initialize(stdin, stdout, debug = false) ⇒ Bash
Returns a new instance of Bash.
31 32 33 34 35 36 |
# File 'lib/cute/bash.rb', line 31 def initialize(stdin, stdout, debug = false) @stdin = stdin @stdout = stdout @debug = debug @buff = '' end |
Instance Method Details
#_escape(args) ⇒ Object
90 91 92 |
# File 'lib/cute/bash.rb', line 90 def _escape(args) return args.map { |x| "'#{x}'" }.join(' ') end |
#_extend(path, suffix) ⇒ Object
81 82 83 84 |
# File 'lib/cute/bash.rb', line 81 def _extend(path, suffix) path = path.chomp('/') if path.end_with?('/') return path + suffix end |
#_loop ⇒ Object
42 43 44 45 46 47 48 49 50 51 |
# File 'lib/cute/bash.rb', line 42 def _loop while true do x = IO::select([@stdout], [], [], 120.0) raise BashTimeout.new if x.nil? bytes = @stdout.sysread(1024) $stderr.write("\nBASH IN: #{bytes}\n") if @debug @buff << bytes break if yield end end |
#_nonce ⇒ Object
53 54 55 56 |
# File 'lib/cute/bash.rb', line 53 def _nonce randee = 4.times.map { rand().to_s }.join('|') return Digest::SHA512.hexdigest(randee).to_s end |
#_run(cmd, _opts) ⇒ Object
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/cute/bash.rb', line 58 def _run(cmd, _opts) # it's a kind of magic $stderr.write("\nBASH CMD: #{cmd}\n") if @debug nonce = _nonce() @stdin.write("#{cmd}; printf '%04d#{nonce}' $?\n") @stdin.flush _loop do @buff.include?(nonce) end raise BashPaddingError.new if !@buff.end_with?(nonce) output = @buff @buff = '' # treat the output output.slice!(-nonce.length..-1) status = output.slice!(-4..-1) raise "Status #{status} > 255?" if status.slice(0..0) != '0' return output, status.to_i end |
#_run_block(cmd, _opts) ⇒ Object
77 78 79 |
# File 'lib/cute/bash.rb', line 77 def _run_block(cmd, _opts) @stdin.write("#{cmd}; printf '%04d#{nonce}' $?\n") end |
#_unlines(s) ⇒ Object
86 87 88 |
# File 'lib/cute/bash.rb', line 86 def _unlines(s) return s.lines.map { |l| l.chomp("\n") } end |
#abspath(path) ⇒ Object
167 168 169 |
# File 'lib/cute/bash.rb', line 167 def abspath(path) run("readlink -f #{path}").strip end |
#append_line(path, line) ⇒ Object
252 253 254 |
# File 'lib/cute/bash.rb', line 252 def append_line(path, line) return run("echo '#{line}' >> #{path}") end |
#append_lines(path, lines) ⇒ Object
256 257 258 259 260 |
# File 'lib/cute/bash.rb', line 256 def append_lines(path, lines) lines.each { |line| append_line(path, line) } end |
#aptget(*args) ⇒ Object
287 288 289 290 291 292 293 294 295 296 |
# File 'lib/cute/bash.rb', line 287 def aptget(*args) raise 'Command not given' if args.length == 0 cmd = args.first.to_sym args = args.map { |x| x.to_s }.join(' ') status = run_status("DEBIAN_FRONTEND=noninteractive apt-get -y #{args}") if cmd == :purge and status == 100 return # ugly hack for the case when the package is not installed end raise StatusError.new('aptget', status, 'none') if status != 0 end |
#assert(condition, msg = 'Assertion error') ⇒ Object
TESTING METHODS
96 97 98 |
# File 'lib/cute/bash.rb', line 96 def assert(condition, msg = 'Assertion error') raise msg if condition != true end |
#bc(text) ⇒ Object
141 142 143 |
# File 'lib/cute/bash.rb', line 141 def bc(text) run("echo '#{text}' | bc").strip end |
#build ⇒ Object
161 162 163 164 165 |
# File 'lib/cute/bash.rb', line 161 def build # builds a standard Unix software run("./configure") run("make") end |
#build_tarball(tarball, path) ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/cute/bash.rb', line 171 def build_tarball(tarball, path) # builds a tarball containing a std Unix software tarball = abspath(tarball) path = abspath(path) remove_dirs(path) tmp = _extend(path, '-tmp') remove_dirs(tmp) make_dirs(tmp) untar(tarball, tmp) cd tmp # we are in the temp dir if exists('./configure') cd '/' mv tmp, path else ds = dirs() raise 'Too many dirs?' if ds.length != 1 mv ds.first, path cd '/' remove_dirs(tmp) end cd path build end |
#cd(path) ⇒ Object
117 118 119 |
# File 'lib/cute/bash.rb', line 117 def cd(path) run("cd #{path}") end |
#contents(name) ⇒ Object Also known as: cat
262 263 264 |
# File 'lib/cute/bash.rb', line 262 def contents(name) run("cat #{name}") end |
#cp(a, b) ⇒ Object
145 146 147 |
# File 'lib/cute/bash.rb', line 145 def cp(a, b) run("cp #{a} #{b}") end |
#dirs(ignore = true) ⇒ Object
238 239 240 |
# File 'lib/cute/bash.rb', line 238 def dirs(ignore = true) return files(ignore, 'd') end |
#distribute(path, dest, *nodes) ⇒ Object
298 299 300 301 302 303 |
# File 'lib/cute/bash.rb', line 298 def distribute(path, dest, *nodes) # distributes a file to the given nodes nodes.flatten.each { |node| run("scp -o 'StrictHostKeyChecking no' #{path} #{node}:#{dest}") } end |
#echo(text) ⇒ Object
137 138 139 |
# File 'lib/cute/bash.rb', line 137 def echo(text) run("echo #{text}") end |
#exists(path) ⇒ Object
215 216 217 |
# File 'lib/cute/bash.rb', line 215 def exists(path) run_status("[[ -e #{path} ]]") == 0 end |
#expand_path(path) ⇒ Object
248 249 250 |
# File 'lib/cute/bash.rb', line 248 def (path) return run("echo #{path}").strip end |
#export(name, value) ⇒ Object
PUBLIC METHODS
102 103 104 |
# File 'lib/cute/bash.rb', line 102 def export(name, value) run("export #{name}=#{value}") end |
#files(ignore = true, type = 'f') ⇒ Object
227 228 229 230 231 232 |
# File 'lib/cute/bash.rb', line 227 def files(ignore = true, type = 'f') fs = run("find . -maxdepth 1 -type #{type}") fs = _unlines(fs).reject { |f| f == '.' }.map { |f| f[2..-1] } fs = fs.reject { |f| f.end_with?('~') or f.start_with?('.') } if ignore return fs end |
#get_type(name) ⇒ Object
242 243 244 245 246 |
# File 'lib/cute/bash.rb', line 242 def get_type(name) return :dir if run_status("[[ -d #{name} ]]") == 0 return :file if run_status("[[ -f #{name} ]]") == 0 raise "'#{name}' is neither file nor directory" end |
#glob(pattern) ⇒ Object
305 306 307 308 309 |
# File 'lib/cute/bash.rb', line 305 def glob(pattern) out, status = _run("ls -1 #{pattern}", {}) return [] if status != 0 return out.strip.lines.map { |x| x.strip } end |
#hostname ⇒ Object
268 269 270 |
# File 'lib/cute/bash.rb', line 268 def hostname return run('hostname').strip end |
#join(*args) ⇒ Object
211 212 213 |
# File 'lib/cute/bash.rb', line 211 def join(*args) return File.join(*args) end |
#ls ⇒ Object
121 122 123 |
# File 'lib/cute/bash.rb', line 121 def ls run("ls -1").lines.map { |line| line.chomp("\n") } end |
#make_dirs(path) ⇒ Object
219 220 221 |
# File 'lib/cute/bash.rb', line 219 def make_dirs(path) run("mkdir -p #{path}") end |
#mkdir(path) ⇒ Object
223 224 225 |
# File 'lib/cute/bash.rb', line 223 def mkdir(path) run("mkdir #{path}") unless exists(path) # TODO: this changes semantics of mkdir... end |
#mpirun(machines, params) ⇒ Object
206 207 208 209 |
# File 'lib/cute/bash.rb', line 206 def mpirun(machines, params) machines = save_machines(machines) if machines.is_a?(Array) return run("mpirun --mca btl ^openib -machinefile #{machines} #{params}") end |
#mv(a, b) ⇒ Object
149 150 151 |
# File 'lib/cute/bash.rb', line 149 def mv(a, b) run("mv #{a} #{b}") end |
#packages ⇒ Object
279 280 281 282 283 284 285 |
# File 'lib/cute/bash.rb', line 279 def packages list = run("dpkg -l") _unlines(list).map do |p| s, n, v = p.split { :status => s, :name => n, :version => v } end end |
#parse(&block) ⇒ Object
38 39 40 |
# File 'lib/cute/bash.rb', line 38 def parse(&block) return self.instance_exec(&block) end |
#pwd ⇒ Object
125 126 127 |
# File 'lib/cute/bash.rb', line 125 def pwd run("pwd").strip end |
#remove_dirs(path) ⇒ Object
157 158 159 |
# File 'lib/cute/bash.rb', line 157 def remove_dirs(path) rm "-rf", path end |
#rm(*args) ⇒ Object
153 154 155 |
# File 'lib/cute/bash.rb', line 153 def rm(*args) run("rm #{_escape(args)}") end |
#run(cmd, opts = {}) ⇒ Object
106 107 108 109 110 |
# File 'lib/cute/bash.rb', line 106 def run(cmd, opts = {}) out, status = _run(cmd, opts) raise StatusError.new(cmd, status, out) if status != 0 return out end |
#run_status(cmd, opts = {}) ⇒ Object
112 113 114 115 |
# File 'lib/cute/bash.rb', line 112 def run_status(cmd, opts = {}) _out, status = _run(cmd, opts) return status end |
#save_machines(machines, path = nil) ⇒ Object
200 201 202 203 204 |
# File 'lib/cute/bash.rb', line 200 def save_machines(machines, path = nil) path = tmp_file if path.nil? append_lines(path, machines.map { |m| m.to_s }) return path end |
#tmp_file ⇒ Object
196 197 198 |
# File 'lib/cute/bash.rb', line 196 def tmp_file return run('mktemp').strip end |
#touch(path) ⇒ Object
272 273 274 |
# File 'lib/cute/bash.rb', line 272 def touch(path) run("touch #{path}") end |
#untar(name, where = nil) ⇒ Object
129 130 131 132 133 134 135 |
# File 'lib/cute/bash.rb', line 129 def untar(name, where = nil) if where.nil? run("tar xvf #{name}") else run("tar -C #{where} -xvf #{name}") end end |
#which(prog) ⇒ Object
234 235 236 |
# File 'lib/cute/bash.rb', line 234 def which(prog) return run("which #{prog}").strip end |