Class: EasySH
Overview
EasySH examples:
sh = EasySH.new
# basic usage
puts sh.ls
puts sh['/bin/ls']
# command parameters
puts sh.ls['/bin']._l
puts sh.ls._l '/bin'
puts sh.ls('/bin', :l, :color => :always)
puts sh['/bin/ls', '-l', :color => :always]
# enumerable
sh.ls.max
sh.ls.sort
sh.ls.chars.to_a.sample(5)
sh.cat('/dev/urandom').bytes.first(10)
sh.ls._l.map{|l| l.split}
sh.ps._e._o('euser,comm').map(&:split).group_by(&:first)
# chaining commands
sudo = sh.sudo
tail = sh.tail
sudo[tail._f '/var/log/everything.log'].lines { |l| puts l.upcase }
sudo.tail._f '/var/log/everything.log' do |l| puts l.upcase end
lab = sh.ssh['lab'] # or, sh.ssh.lab
puts lab.ls._l '/bin', color: :always
# redirects
puts sh.echo('hello') > '/tmp/test'
puts sh.echo 'hello', 1 => '/tmp/stdout', 2 => '/tmp/stderr'
puts sh.cat < '/tmp/test'
puts sh.cat 0 => '/tmp/fffff'
# pipes
puts sh.man('ls') | sh.tail(n: 30) | sh.head(:n, 4)
grep = sh['grep']
filter = grep['problem'] | grep._v['bugs']
puts sh.man.ls | filter
kat = sh.cat
puts kat['/tmp/foo'] | (kat | kat | kat.|(kat) | (kat | kat) | (kat | kat))
# exit status
p = sh.which('bash')
puts p
p.exitstatus # => #<Process::Status: pid 5931 exit 0>
p = sh.which.nonexists
puts p
p.exitstatus # => #<Process::Status: pid 6156 exit 1>
# instant mode
# tired with 'puts' and 'to_s' in REPL? just set instant = true
# [2] pry(main)> sh.instant = false; sh.uptime
# => #<EasySH: uptime>
# [3] pry(main)> sh.instant = true; sh.uptime
# => 22:14:23 up 1 day, 4:02, 12 users, load average: 0.69, 0.65, 0.67
# [4] pry(main)> sh = EasySH.instant; sh.uname
# => Linux
Instance Attribute Summary collapse
-
#chain ⇒ Object
Returns the value of attribute chain.
-
#cmd ⇒ Object
Returns the value of attribute cmd.
-
#exitstatus ⇒ Object
readonly
Returns the value of attribute exitstatus.
-
#instant ⇒ Object
Returns the value of attribute instant.
-
#opt ⇒ Object
Returns the value of attribute opt.
Class Method Summary collapse
Instance Method Summary collapse
- #<(path) ⇒ Object
- #>(path) ⇒ Object
- #each_byte ⇒ Object (also: #bytes)
- #each_char ⇒ Object (also: #chars)
- #each_line ⇒ Object (also: #lines, #each)
- #inspect ⇒ Object
-
#method_missing(name, *args, &block) ⇒ Object
(also: #call, #[])
:no-doc:.
- #pretty_print(q) ⇒ Object
- #to_a ⇒ Object (also: #to_ary)
- #to_io ⇒ Object
- #to_s(n = "\n") ⇒ Object (also: #read, #!)
- #|(sh, &block) ⇒ Object
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object Also known as: call, []
:no-doc:
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 |
# File 'lib/easysh.rb', line 72 def method_missing name, *args, &block # :no-doc: begin return super(name, *args, &block) rescue NoMethodError, ArgumentError => ex # continue end r = if name.is_a? EasySH self.class.new [*cmd, *name.cmd], Hash[*opt, *name.opt], chain, instant else args = [name.to_s.gsub(/^_+/) {|s| '-' * s.size}, *args] *args, opt = *args if args.last.is_a?(Hash) && args.last.keys.find{|k| k.is_a? Integer} args = args.map do |a| case a when Symbol "-#{a.length > 1 ? '-' : ''}#{a}" when Hash a.map { |k,v| k.length > 1 ? "--#{k}=#{v}" : "-#{k} #{v}" } else a.to_s end end.flatten self.class.new [*cmd, *args], Hash[[*self.opt, *opt]], chain, instant end block ? r.each(&block) : r end |
Instance Attribute Details
#chain ⇒ Object
Returns the value of attribute chain
67 68 69 |
# File 'lib/easysh.rb', line 67 def chain @chain end |
#cmd ⇒ Object
Returns the value of attribute cmd
67 68 69 |
# File 'lib/easysh.rb', line 67 def cmd @cmd end |
#exitstatus ⇒ Object (readonly)
Returns the value of attribute exitstatus.
70 71 72 |
# File 'lib/easysh.rb', line 70 def exitstatus @exitstatus end |
#instant ⇒ Object
Returns the value of attribute instant
67 68 69 |
# File 'lib/easysh.rb', line 67 def instant @instant end |
#opt ⇒ Object
Returns the value of attribute opt
67 68 69 |
# File 'lib/easysh.rb', line 67 def opt @opt end |
Class Method Details
.instant ⇒ Object
181 182 183 |
# File 'lib/easysh.rb', line 181 def self.instant new(nil, {}, [], true) end |
Instance Method Details
#<(path) ⇒ Object
111 |
# File 'lib/easysh.rb', line 111 def < path; self.opt[0] = path; self; end |
#>(path) ⇒ Object
112 |
# File 'lib/easysh.rb', line 112 def > path; self.opt[1] = path; self; end |
#each_byte ⇒ Object Also known as: bytes
161 162 163 164 |
# File 'lib/easysh.rb', line 161 def each_byte return to_enum(:each_byte) unless block_given? to_io { |i| while b = i.getbyte; yield b; end } end |
#each_char ⇒ Object Also known as: chars
156 157 158 159 |
# File 'lib/easysh.rb', line 156 def each_char return to_enum(:each_char) unless block_given? to_io { |i| while c = i.getc; yield c; end } end |
#each_line ⇒ Object Also known as: lines, each
151 152 153 154 |
# File 'lib/easysh.rb', line 151 def each_line return to_enum(:each_line) unless block_given? to_io { |i| while l = i.gets; yield l.chomp; end } end |
#inspect ⇒ Object
102 103 104 |
# File 'lib/easysh.rb', line 102 def inspect instant ? to_s : "#<#{self.class}: #{([*chain, [cmd]]).map(&:first).map {|c| c && c.join(' ')}.compact.join(' | ')}>" end |
#pretty_print(q) ⇒ Object
177 178 179 |
# File 'lib/easysh.rb', line 177 def pretty_print(q) q.text self.inspect end |
#to_a ⇒ Object Also known as: to_ary
99 |
# File 'lib/easysh.rb', line 99 def to_a; each.to_a; end |
#to_io ⇒ Object
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 141 142 143 144 145 146 147 148 149 |
# File 'lib/easysh.rb', line 114 def to_io return unless cmd cur_opt = opt.clone cur_chain = (chain || []) + [[cmd, cur_opt]] pipes = cur_chain.map { IO.pipe } n = pipes.size cur_opt[0] = pipes[n-1][0] if n > 1 lpid, lopt = nil pids = [] begin cur_chain.reverse.each_with_index do |cmd_opt, i| i = n - 1 - i c, o = *cmd_opt o = o.clone o[1] = nil if i < n - 1 o[1] ||= pipes[i][1] o[0] = pipes[i-1][0] if i > 0 pid = spawn(*c, o) pids << pid lopt, lpid = o, pid if i == n - 1 end if lopt[1] == pipes[n-1][1] rfd = pipes[n-1][0] (pipes.flatten-[rfd]).each { |io| io.close unless io.closed? } yield rfd end ensure pipes.flatten.each { |io| io.close unless io.closed? } @exitstatus = Process.wait2(lpid)[-1] rescue nil ['TERM', 'KILL'].each { |sig| Process.kill sig, *pids rescue nil } Process.waitall rescue nil end end |
#to_s(n = "\n") ⇒ Object Also known as: read, !
100 |
# File 'lib/easysh.rb', line 100 def to_s(n = "\n"); cmd ? to_a.join(n) : ''; end |
#|(sh, &block) ⇒ Object
106 107 108 109 |
# File 'lib/easysh.rb', line 106 def |(sh, &block) raise TypeError.new("EasySH expected, got #{sh.inspect}") unless sh.is_a? EasySH self.class.new sh.cmd, sh.opt, [*chain, cmd && [cmd, opt || {}], *sh.chain].compact, instant end |