1 -- shell.rb
2				$Release Version: 0.6.0 $
3			   	$Revision: 33181 $
4			   	by Keiju ISHITSUKA(keiju@ishitsuka.com)
5
6=begin
7
8= 目的
9
10ruby上でsh/cshのようにコマンドの実行及びフィルタリングを手軽に行う.
11sh/cshの制御文はrubyの機能を用いて実現する.
12
13= 主なクラス一覧
14
15== Shell
16
17Shellオブジェクトはカレントディレクトリを持ち, コマンド実行はそこからの
18相対パスになります.
19
20--- Shell#cwd
21--- Shell#dir
22--- Shell#getwd
23--- Shell#pwd
24
25      カレントディレクトリを返す。
26
27--- Shell#system_path
28
29      コマンドサーチパスの配列を返す。
30
31--- Shell#umask
32
33      umaskを返す。
34
35== Filter
36
37コマンドの実行結果はすべてFilterとしてかえります. Enumerableをincludeし
38ています.
39
40= 主なメソッド一覧
41
42== コマンド定義
43
44OS上のコマンドを実行するにはまず, Shellのメソッドとして定義します.
45
46注) コマンドを定義しなくとも直接実行できるShell#systemコマンドもあります.
47
48--- Shell.def_system_command(command, path = command)
49
50      Shellのメソッドとしてcommandを登録します. 
51
52      例)
53      Shell.def_system_command "ls"
54        ls を定義
55
56      Shell.def_system_command "sys_sort", "sort"
57        sortコマンドをsys_sortとして定義
58
59--- Shell.undef_system_command(command)
60
61      commandを削除します.
62
63--- Shell.alias_command(ali, command, *opts) {...}
64
65      commandのaliasをします. 
66
67      例)
68        Shell.alias_command "lsC", "ls", "-CBF", "--show-control-chars"
69        Shell.alias_command("lsC", "ls"){|*opts| ["-CBF", "--show-control-chars", *opts]}
70
71--- Shell.unalias_command(ali)
72
73      commandのaliasを削除します.
74
75--- Shell.install_system_commands(pre = "sys_")
76
77      system_path上にある全ての実行可能ファイルをShellに定義する. メソッ
78      ド名は元のファイル名の頭にpreをつけたものとなる.
79
80== 生成
81
82--- Shell.new
83
84      プロセスのカレントディレクトリをカレントディレクトリとするShellオ
85      ブジェクトを生成します.
86
87--- Shell.cd(path)
88
89      pathをカレントディレクトリとするShellオブジェクトを生成します.
90
91== プロセス管理
92
93--- Shell#jobs
94
95      スケジューリングされているjobの一覧を返す.
96
97--- Shell#kill sig, job
98
99      jobにシグナルsigを送る
100
101== カレントディレクトリ操作
102
103--- Shell#cd(path, &block)
104--- Shell#chdir
105
106      カレントディレクトリをpathにする. イテレータとして呼ばれたときには
107      ブロック実行中のみカレントディレクトリを変更する.
108
109--- Shell#pushd(path = nil, &block)
110--- Shell#pushdir
111
112      カレントディレクトリをディレクトリスタックにつみ, カレントディレク
113      トリをpathにする. pathが省略されたときには, カレントディレクトリと
114      ディレクトリスタックのトップを交換する. イテレータとして呼ばれたと
115      きには, ブロック実行中のみpushdする.
116
117--- Shell#popd
118--- Shell#popdir
119
120      ディレクトリスタックからポップし, それをカレントディレクトリにする.
121
122== ファイル/ディレクトリ操作
123
124--- Shell#foreach(path = nil, &block)
125
126      pathがファイルなら, File#foreach
127      pathがディレクトリなら, Dir#foreach
128
129--- Shell#open(path, mode)
130
131      pathがファイルなら, File#open
132      pathがディレクトリなら, Dir#open
133
134--- Shell#unlink(path)
135
136      pathがファイルなら, File#unlink
137      pathがディレクトリなら, Dir#unlink
138
139--- Shell#test(command, file1, file2)
140--- Shell#[command, file1, file2]
141
142      ファイルテスト関数testと同じ. 
143      例)
144          sh[?e, "foo"]
145          sh[:e, "foo"]
146          sh["e", "foo"]
147          sh[:exists?, "foo"]
148          sh["exists?", "foo"]
149
150--- Shell#mkdir(*path)
151
152      Dir.mkdirと同じ(複数可)
153
154--- Shell#rmdir(*path)
155
156      Dir.rmdirと同じ(複数可)
157
158== コマンド実行
159
160--- System#system(command, *opts)
161
162      commandを実行する.
163      例)
164        print sh.system("ls", "-l")
165        sh.system("ls", "-l") | sh.head > STDOUT
166
167--- System#rehash
168
169      リハッシュする
170
171--- Shell#transact &block
172
173      ブロック中ではshellをselfとして実行する.
174      例)
175        sh.transact{system("ls", "-l") | head > STDOUT}
176
177--- Shell#out(dev = STDOUT, &block)
178
179      transactを呼び出しその結果をdevに出力する.
180
181== 内部コマンド
182
183--- Shell#echo(*strings)
184--- Shell#cat(*files)
185--- Shell#glob(patten)
186--- Shell#tee(file)
187
188      これらは実行すると, それらを内容とするFilterオブジェクトを返します. 
189
190--- Filter#each &block
191
192      フィルタの一行ずつをblockに渡す.
193
194--- Filter#<(src)
195
196      srcをフィルタの入力とする. srcが, 文字列ならばファイルを, IOであれ
197      ばそれをそのまま入力とする.
198
199--- Filter#>(to)
200
201      srcをフィルタの出力とする. toが, 文字列ならばファイルに, IOであれ
202      ばそれをそのまま出力とする.
203
204--- Filter#>>(to)
205
206      srcをフィルタに追加する. toが, 文字列ならばファイルに, IOであれば
207      それをそのまま出力とする.
208
209--- Filter#|(filter)
210
211      パイプ結合
212
213--- Filter#+(filter)
214
215      filter1 + filter2 は filter1の出力の後, filter2の出力を行う.
216
217--- Filter#to_a
218--- Filter#to_s
219
220== 組込みコマンド
221
222--- Shell#atime(file)
223--- Shell#basename(file, *opt)
224--- Shell#chmod(mode, *files)
225--- Shell#chown(owner, group, *file)
226--- Shell#ctime(file)
227--- Shell#delete(*file)
228--- Shell#dirname(file)
229--- Shell#ftype(file)
230--- Shell#join(*file)
231--- Shell#link(file_from, file_to)
232--- Shell#lstat(file)
233--- Shell#mtime(file)
234--- Shell#readlink(file)
235--- Shell#rename(file_from, file_to)
236--- Shell#split(file)
237--- Shell#stat(file)
238--- Shell#symlink(file_from, file_to)
239--- Shell#truncate(file, length)
240--- Shell#utime(atime, mtime, *file)
241
242      これらはFileクラスにある同名のクラスメソッドと同じです.
243
244--- Shell#blockdev?(file)
245--- Shell#chardev?(file)
246--- Shell#directory?(file)
247--- Shell#executable?(file)
248--- Shell#executable_real?(file)
249--- Shell#exist?(file)/Shell#exists?(file)
250--- Shell#file?(file)
251--- Shell#grpowned?(file)
252--- Shell#owned?(file)
253--- Shell#pipe?(file)
254--- Shell#readable?(file)
255--- Shell#readable_real?(file)
256--- Shell#setgid?(file)
257--- Shell#setuid?(file)
258--- Shell#size(file)/Shell#size?(file)
259--- Shell#socket?(file)
260--- Shell#sticky?(file)
261--- Shell#symlink?(file)
262--- Shell#writable?(file)
263--- Shell#writable_real?(file)
264--- Shell#zero?(file)
265
266      これらはFileTestクラスにある同名のクラスメソッドと同じです.
267
268--- Shell#syscopy(filename_from, filename_to)
269--- Shell#copy(filename_from, filename_to)
270--- Shell#move(filename_from, filename_to)
271--- Shell#compare(filename_from, filename_to)
272--- Shell#safe_unlink(*filenames)
273--- Shell#makedirs(*filenames)
274--- Shell#install(filename_from, filename_to, mode)
275
276      これらはFileToolsクラスにある同名のクラスメソッドと同じです.
277
278      その他, 以下のものがエイリアスされています.
279
280--- Shell#cmp	<- Shell#compare
281--- Shell#mv	<- Shell#move
282--- Shell#cp	<- Shell#copy
283--- Shell#rm_f	<- Shell#safe_unlink
284--- Shell#mkpath	<- Shell#makedirs
285
286= サンプル
287
288== ex1
289
290  sh = Shell.cd("/tmp")
291  sh.mkdir "shell-test-1" unless sh.exists?("shell-test-1")
292  sh.cd("shell-test-1")
293  for dir in ["dir1", "dir3", "dir5"]
294    if !sh.exists?(dir)
295      sh.mkdir dir
296      sh.cd(dir) do
297	f = sh.open("tmpFile", "w")
298	f.print "TEST\n"
299	f.close
300      end
301      print sh.pwd
302    end
303  end
304
305== ex2
306
307  sh = Shell.cd("/tmp")
308  sh.transact do
309    mkdir "shell-test-1" unless exists?("shell-test-1")
310    cd("shell-test-1")
311    for dir in ["dir1", "dir3", "dir5"]
312      if !exists?(dir)
313	mkdir dir
314	cd(dir) do
315	  f = open("tmpFile", "w")
316	  f.print "TEST\n"
317	  f.close
318	end
319	print pwd
320      end
321    end
322  end
323
324== ex3
325
326  sh.cat("/etc/printcap") | sh.tee("tee1") > "tee2"
327  (sh.cat < "/etc/printcap") | sh.tee("tee11") > "tee12"
328  sh.cat("/etc/printcap") | sh.tee("tee1") >> "tee2"
329  (sh.cat < "/etc/printcap") | sh.tee("tee11") >> "tee12"
330
331== ex4
332
333  print sh.cat("/etc/passwd").head.collect{|l| l =~ /keiju/}
334
335=end
336