rubysh 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ class SelfTeeExample
2
+ def run
3
+ require 'rubysh/plugin/self_tee'
4
+ Rubysh::Plugin::SelfTee.start('/tmp/logfile.txt', [1, 2])
5
+
6
+ puts "this is a line"
7
+ $stderr.puts "this is another line"
8
+ puts "so is this"
9
+ end
10
+ end
11
+
12
+ if $0 == __FILE__
13
+ SelfTeeExample.new.run
14
+ end
@@ -0,0 +1,67 @@
1
+ require 'rubysh'
2
+
3
+ # This is currently unstable. (I'm likely going to flesh out a real
4
+ # plugin interface.)
5
+
6
+ module Rubysh::Plugin
7
+ class SelfTee
8
+ def self.start(logfile, fd_nums)
9
+ fd_map = {}
10
+ fd_nums.each do |fd_num|
11
+ fd = IO.new(fd_num)
12
+ fd.autoclose = false
13
+ fd_map[fd] = IO.pipe
14
+ end
15
+
16
+ fork {child_actions(logfile, fd_map)}
17
+ parent_actions(fd_map)
18
+ end
19
+
20
+ def self.parent_actions(fd_map)
21
+ fd_map.each do |fd, (read, write)|
22
+ read.close
23
+ Rubysh::Util.dup2(write, fd)
24
+ end
25
+ end
26
+
27
+ def self.child_actions(logfile, fd_map)
28
+ runner = self.new(logfile, fd_map)
29
+ runner.run
30
+ end
31
+
32
+ def initialize(filename, fd_map)
33
+ @logfile = File.open(filename, 'a')
34
+ fd_map.each do |fd, (read, write)|
35
+ write.close
36
+ end
37
+
38
+ @readers = {}
39
+ fd_map.map {|fd, (read, write)| @readers[read] = fd}
40
+ end
41
+
42
+ def format_line(fd, line)
43
+ now = Time.now
44
+ now_fmt = now.strftime("%Y-%m-%d %H:%M:%S")
45
+ ms_fmt = sprintf("%06d", now.usec)
46
+
47
+ output = "[#{now_fmt}.#{ms_fmt}] #{fd.fileno}: #{line.inspect}"
48
+ output << "\n" unless output.end_with?("\n")
49
+ output
50
+ end
51
+
52
+ def run
53
+ parallel_io = Rubysh::Subprocess::ParallelIO.new(@readers, [])
54
+ parallel_io.on_read do |fd, data|
55
+ next if data == Rubysh::Subprocess::ParallelIO::EOF
56
+
57
+ formatted = format_line(fd, data)
58
+ @logfile.write(formatted)
59
+ @logfile.flush
60
+
61
+ fd.write(data)
62
+ fd.flush
63
+ end
64
+ parallel_io.run
65
+ end
66
+ end
67
+ end
@@ -1,3 +1,3 @@
1
1
  module Rubysh
2
- VERSION = '0.1.1'
2
+ VERSION = '0.1.2'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubysh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -88,6 +88,7 @@ files:
88
88
  - README.md
89
89
  - Rakefile
90
90
  - examples/dots.sh
91
+ - examples/self_tee_example.rb
91
92
  - lib/rubysh.rb
92
93
  - lib/rubysh/base_command.rb
93
94
  - lib/rubysh/base_directive.rb
@@ -96,6 +97,7 @@ files:
96
97
  - lib/rubysh/fd.rb
97
98
  - lib/rubysh/pipe.rb
98
99
  - lib/rubysh/pipeline.rb
100
+ - lib/rubysh/plugin/self_tee.rb
99
101
  - lib/rubysh/redirect.rb
100
102
  - lib/rubysh/runner.rb
101
103
  - lib/rubysh/subprocess.rb
@@ -140,7 +142,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
140
142
  version: '0'
141
143
  segments:
142
144
  - 0
143
- hash: 2837385941821063747
145
+ hash: 3657158191567713340
144
146
  required_rubygems_version: !ruby/object:Gem::Requirement
145
147
  none: false
146
148
  requirements:
@@ -149,7 +151,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
151
  version: '0'
150
152
  segments:
151
153
  - 0
152
- hash: 2837385941821063747
154
+ hash: 3657158191567713340
153
155
  requirements: []
154
156
  rubyforge_project:
155
157
  rubygems_version: 1.8.23