Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 301 lines (249 sloc) 5.825 kb
511dc44 initial import
Laurent Sansonetti authored
1 #
2 # shell.rb -
3 # $Release Version: 0.7 $
4 # $Revision: 1.9 $
5 # by Keiju ISHITSUKA(keiju@ruby-lang.org)
6 #
7 # --
8 #
9 #
10 #
11
12 require "e2mmap"
13
14 require "thread" unless defined?(Mutex)
15
16 require "forwardable"
17
18 require "shell/error"
19 require "shell/command-processor"
20 require "shell/process-controller"
21
22 class Shell
23 @RCS_ID='-$Id: shell.rb,v 1.9 2002/03/04 12:01:10 keiju Exp keiju $-'
24
25 include Error
26 extend Exception2MessageMapper
27
28 # @cascade = true
29 # debug: true -> normal debug
30 # debug: 1 -> eval definition debug
31 # debug: 2 -> detail inspect debug
32 @debug = false
33 @verbose = true
34
35 @debug_display_process_id = false
36 @debug_display_thread_id = true
37 @debug_output_mutex = Mutex.new
38
39 class << Shell
40 extend Forwardable
41
42 attr_accessor :cascade, :debug, :verbose
43
44 # alias cascade? cascade
45 alias debug? debug
46 alias verbose? verbose
47 @verbose = true
48
49 def debug=(val)
50 @debug = val
51 @verbose = val if val
52 end
53
54 def cd(path)
55 new(path)
56 end
57
58 def default_system_path
59 if @default_system_path
60 @default_system_path
61 else
62 ENV["PATH"].split(":")
63 end
64 end
65
66 def default_system_path=(path)
67 @default_system_path = path
68 end
69
70 def default_record_separator
71 if @default_record_separator
72 @default_record_separator
73 else
74 $/
75 end
76 end
77
78 def default_record_separator=(rs)
79 @default_record_separator = rs
80 end
81
8f21162 @richkilmer bring lib up to r22701 (ruby 1.9.1_0 tag). there are build issues us…
richkilmer authored
82 # os resource mutex
511dc44 initial import
Laurent Sansonetti authored
83 mutex_methods = ["unlock", "lock", "locked?", "synchronize", "try_lock", "exclusive_unlock"]
84 for m in mutex_methods
85 def_delegator("@debug_output_mutex", m, "debug_output_"+m.to_s)
86 end
87
88 end
89
90 def initialize(pwd = Dir.pwd, umask = nil)
91 @cwd = File.expand_path(pwd)
92 @dir_stack = []
93 @umask = umask
94
95 @system_path = Shell.default_system_path
96 @record_separator = Shell.default_record_separator
97
98 @command_processor = CommandProcessor.new(self)
99 @process_controller = ProcessController.new(self)
100
101 @verbose = Shell.verbose
102 @debug = Shell.debug
103 end
104
105 attr_reader :system_path
106
107 def system_path=(path)
108 @system_path = path
109 rehash
110 end
111
112 attr_accessor :umask, :record_separator
113 attr_accessor :verbose, :debug
114
115 def debug=(val)
116 @debug = val
117 @verbose = val if val
118 end
119
120 alias verbose? verbose
121 alias debug? debug
122
123 attr_reader :command_processor
124 attr_reader :process_controller
125
126 def expand_path(path)
127 File.expand_path(path, @cwd)
128 end
129
130 # Most Shell commands are defined via CommandProcessor
131
132 #
133 # Dir related methods
134 #
135 # Shell#cwd/dir/getwd/pwd
136 # Shell#chdir/cd
137 # Shell#pushdir/pushd
138 # Shell#popdir/popd
139 # Shell#mkdir
140 # Shell#rmdir
141
142 attr_reader :cwd
143 alias dir cwd
144 alias getwd cwd
145 alias pwd cwd
146
147 attr_reader :dir_stack
148 alias dirs dir_stack
149
150 # If called as iterator, it restores the current directory when the
151 # block ends.
152 def chdir(path = nil, verbose = @verbose)
153 check_point
154
155 if iterator?
156 notify("chdir(with block) #{path}") if verbose
157 cwd_old = @cwd
158 begin
159 chdir(path, nil)
160 yield
161 ensure
162 chdir(cwd_old, nil)
163 end
164 else
165 notify("chdir #{path}") if verbose
166 path = "~" unless path
167 @cwd = expand_path(path)
168 notify "current dir: #{@cwd}"
169 rehash
170 Void.new(self)
171 end
172 end
173 alias cd chdir
174
175 def pushdir(path = nil, verbose = @verbose)
176 check_point
177
178 if iterator?
179 notify("pushdir(with block) #{path}") if verbose
180 pushdir(path, nil)
181 begin
182 yield
183 ensure
184 popdir
185 end
186 elsif path
187 notify("pushdir #{path}") if verbose
188 @dir_stack.push @cwd
189 chdir(path, nil)
190 notify "dir stack: [#{@dir_stack.join ', '}]"
191 self
192 else
193 notify("pushdir") if verbose
194 if pop = @dir_stack.pop
195 @dir_stack.push @cwd
196 chdir pop
197 notify "dir stack: [#{@dir_stack.join ', '}]"
198 self
199 else
200 Shell.Fail DirStackEmpty
201 end
202 end
203 Void.new(self)
204 end
205 alias pushd pushdir
206
207 def popdir
208 check_point
209
210 notify("popdir")
211 if pop = @dir_stack.pop
212 chdir pop
213 notify "dir stack: [#{@dir_stack.join ', '}]"
214 self
215 else
216 Shell.Fail DirStackEmpty
217 end
218 Void.new(self)
219 end
220 alias popd popdir
221
222 #
223 # process management
224 #
225 def jobs
226 @process_controller.jobs
227 end
228
229 def kill(sig, command)
230 @process_controller.kill_job(sig, command)
231 end
232
233 #
234 # command definitions
235 #
236 def Shell.def_system_command(command, path = command)
237 CommandProcessor.def_system_command(command, path)
238 end
239
240 def Shell.undef_system_command(command)
241 CommandProcessor.undef_system_command(command)
242 end
243
244 def Shell.alias_command(ali, command, *opts, &block)
245 CommandProcessor.alias_command(ali, command, *opts, &block)
246 end
247
248 def Shell.unalias_command(ali)
249 CommandProcessor.unalias_command(ali)
250 end
251
252 def Shell.install_system_commands(pre = "sys_")
253 CommandProcessor.install_system_commands(pre)
254 end
255
256 #
257 def inspect
258 if debug.kind_of?(Integer) && debug > 2
259 super
260 else
261 to_s
262 end
263 end
264
265 def self.notify(*opts, &block)
266 Shell::debug_output_synchronize do
267 if opts[-1].kind_of?(String)
268 yorn = verbose?
269 else
270 yorn = opts.pop
271 end
272 return unless yorn
273
274 if @debug_display_thread_id
275 if @debug_display_process_id
276 prefix = "shell(##{Process.pid}:#{Thread.current.to_s.sub("Thread", "Th")}): "
277 else
278 prefix = "shell(#{Thread.current.to_s.sub("Thread", "Th")}): "
279 end
280 else
281 prefix = "shell: "
282 end
283 _head = true
284 STDERR.print opts.collect{|mes|
285 mes = mes.dup
286 yield mes if iterator?
287 if _head
288 _head = false
289 # "shell" " + mes
290 prefix + mes
291 else
292 " "* prefix.size + mes
293 end
294 }.join("\n")+"\n"
295 end
296 end
297
298 CommandProcessor.initialize
299 CommandProcessor.run_config
300 end
Something went wrong with that request. Please try again.