rev |
line source |
meillo@49
|
1 .so style
|
meillo@42
|
2
|
meillo@0
|
3 .TL
|
meillo@42
|
4 .ps +4
|
meillo@6
|
5 Why the Unix Philosophy still matters
|
meillo@0
|
6 .AU
|
meillo@0
|
7 markus schnalke <meillo@marmaro.de>
|
meillo@0
|
8 .AB
|
meillo@1
|
9 .ti \n(.iu
|
meillo@39
|
10 This paper explains the importance of the Unix Philosophy for software design.
|
meillo@0
|
11 Today, few software designers are aware of these concepts,
|
meillo@39
|
12 and thus a lot of modern software is more limited than necessary
|
meillo@39
|
13 and makes less use of software leverage than possible.
|
meillo@38
|
14 Knowing and following the guidelines of the Unix Philosophy makes software more valuable.
|
meillo@0
|
15 .AE
|
meillo@0
|
16
|
meillo@2
|
17 .FS
|
meillo@2
|
18 .ps -1
|
meillo@39
|
19 This paper was prepared for the ``Software Analysis'' seminar at University Ulm.
|
meillo@47
|
20 Mentor was professor Franz Schweiggert.
|
meillo@55
|
21 Handed in on 2010-04-16.
|
meillo@39
|
22 You may retrieve this document from
|
meillo@39
|
23 .CW \s-1http://marmaro.de/docs \ .
|
meillo@2
|
24 .FE
|
meillo@2
|
25
|
meillo@48
|
26 .H 1 Introduction
|
meillo@0
|
27 .LP
|
meillo@40
|
28 The Unix Philosophy is the essence of how the Unix operating system,
|
meillo@40
|
29 especially its toolchest, was designed.
|
meillo@57
|
30 It is not a limited set of fixed rules,
|
meillo@40
|
31 but a loose set of guidelines which tell how to write software that
|
meillo@57
|
32 suites Unix well.
|
meillo@57
|
33 Actually, the Unix Philosophy describes what is common in typical Unix software.
|
meillo@40
|
34 The Wikipedia has an accurate definition:
|
meillo@40
|
35 .[
|
meillo@44
|
36 wikipedia
|
meillo@44
|
37 unix philosophy
|
meillo@40
|
38 .]
|
meillo@40
|
39 .QP
|
meillo@40
|
40 The \fIUnix philosophy\fP is a set of cultural norms and philosophical
|
meillo@40
|
41 approaches to developing software based on the experience of leading
|
meillo@40
|
42 developers of the Unix operating system.
|
meillo@1
|
43 .PP
|
meillo@40
|
44 As there is no single definition of the Unix Philosophy,
|
meillo@40
|
45 several people have stated their view on what it comprises.
|
meillo@1
|
46 Best known are:
|
meillo@1
|
47 .IP \(bu
|
meillo@1
|
48 Doug McIlroy's summary: ``Write programs that do one thing and do it well.''
|
meillo@1
|
49 .[
|
meillo@44
|
50 mahoney
|
meillo@44
|
51 oral history
|
meillo@1
|
52 .]
|
meillo@1
|
53 .IP \(bu
|
meillo@1
|
54 Mike Gancarz' book ``The UNIX Philosophy''.
|
meillo@1
|
55 .[
|
meillo@44
|
56 gancarz
|
meillo@44
|
57 unix philosophy
|
meillo@1
|
58 .]
|
meillo@1
|
59 .IP \(bu
|
meillo@1
|
60 Eric S. Raymond's book ``The Art of UNIX Programming''.
|
meillo@1
|
61 .[
|
meillo@44
|
62 raymond
|
meillo@44
|
63 art of unix programming
|
meillo@1
|
64 .]
|
meillo@0
|
65 .LP
|
meillo@1
|
66 These different views on the Unix Philosophy have much in common.
|
meillo@40
|
67 Especially, the main concepts are similar in all of them.
|
meillo@40
|
68 McIlroy's definition can surely be called the core of the Unix Philosophy,
|
meillo@57
|
69 but the fundamental idea behind it all is ``small is beautiful''.
|
meillo@40
|
70
|
meillo@40
|
71 .PP
|
meillo@45
|
72 The Unix Philosophy explains how to design good software for Unix.
|
meillo@57
|
73 Many concepts described here are based on Unix facilities.
|
meillo@40
|
74 Other operating systems may not offer such facilities,
|
meillo@57
|
75 hence it may not be possible to design software for such systems
|
meillo@57
|
76 according to the Unix Philosophy.
|
meillo@40
|
77 .PP
|
meillo@57
|
78 The Unix Philosophy has an idea of what the process of software development
|
meillo@41
|
79 should look like, but large parts of the philosophy are quite independent
|
meillo@45
|
80 from a concrete development process.
|
meillo@41
|
81 However, one will soon recognize that some development processes work well
|
meillo@41
|
82 with the ideas of the Unix Philosophy and support them, while others are
|
meillo@41
|
83 at cross-purposes.
|
meillo@45
|
84 Kent Beck's books about Extreme Programming are valuable supplemental
|
meillo@45
|
85 resources on this topic.
|
meillo@1
|
86 .PP
|
meillo@57
|
87 The question of how to actually write code and how the code should look
|
meillo@57
|
88 in detail, are beyond the scope of this paper.
|
meillo@57
|
89 Kernighan and Pike's book ``The Practice of Programming''
|
meillo@41
|
90 .[
|
meillo@44
|
91 kernighan pike
|
meillo@44
|
92 practice of programming
|
meillo@41
|
93 .]
|
meillo@57
|
94 covers this topic.
|
meillo@57
|
95 Its point of view corresponds to the one espoused in this paper.
|
meillo@0
|
96
|
meillo@48
|
97 .H 1 "Importance of software design in general
|
meillo@0
|
98 .LP
|
meillo@57
|
99 Software design consists of planning how the internal structure
|
meillo@57
|
100 and external interfaces of software should look.
|
meillo@39
|
101 It has nothing to do with visual appearance.
|
meillo@57
|
102 If we were to compare a program to a car, then its color would not matter.
|
meillo@39
|
103 Its design would be the car's size, its shape, the locations of doors,
|
meillo@45
|
104 the passenger/space ratio, the available controls and instruments,
|
meillo@45
|
105 and so forth.
|
meillo@39
|
106 .PP
|
meillo@57
|
107 Why should software be designed at all?
|
meillo@57
|
108 It is accepted as general knowledge,
|
meillo@57
|
109 that even a bad plan is better than no plan.
|
meillo@57
|
110 Not designing software means programming without a plan.
|
meillo@57
|
111 This will surely lead to horrible results,
|
meillo@57
|
112 being horrible to use and horrible to maintain.
|
meillo@39
|
113 These two aspects are the visible ones.
|
meillo@45
|
114 Often invisible though, are the wasted possible gains.
|
meillo@39
|
115 Good software design can make these gains available.
|
meillo@2
|
116 .PP
|
meillo@57
|
117 A software's design deals with qualitative properties.
|
meillo@39
|
118 Good design leads to good quality, and quality is important.
|
meillo@57
|
119 Any car may be able to drive from point A to point B,
|
meillo@57
|
120 but it depends on the qualitative decisions made in the design of the vehicle,
|
meillo@57
|
121 whether it is a good choice for passenger transport or not,
|
meillo@57
|
122 whether it is a good choice for a rough mountain area,
|
meillo@57
|
123 and whether the ride will be fun.
|
meillo@39
|
124
|
meillo@2
|
125 .PP
|
meillo@57
|
126 Requirements for a piece of software are twofold:
|
meillo@39
|
127 functional and non-functional.
|
meillo@39
|
128 .IP \(bu
|
meillo@57
|
129 Functional requirements directly define the software's functions.
|
meillo@39
|
130 They are the reason why software gets written.
|
meillo@39
|
131 Someone has a problem and needs a tool to solve it.
|
meillo@39
|
132 Being able to solve the problem is the main functional goal.
|
meillo@57
|
133 This is the driving force behind all programming effort.
|
meillo@39
|
134 Functional requirements are easier to define and to verify.
|
meillo@39
|
135 .IP \(bu
|
meillo@45
|
136 Non-functional requirements are called \fIquality\fP requirements, too.
|
meillo@57
|
137 The quality of software shows through the properties that are not directly
|
meillo@57
|
138 related to the software's basic functions.
|
meillo@45
|
139 Tools of bad quality often do solve the problems they were written for,
|
meillo@57
|
140 but introduce problems and difficulties for usage and development later on.
|
meillo@57
|
141 Qualitative aspects are often overlooked at first sight,
|
meillo@45
|
142 and are often difficult to define clearly and to verify.
|
meillo@2
|
143 .PP
|
meillo@54
|
144 Quality is hardly interesting when software gets built initially,
|
meillo@57
|
145 but it has a high impact on usability and maintenance of the software later.
|
meillo@57
|
146 A short-sighted person might see the process of developing software as
|
meillo@57
|
147 one mainly concerned with building something up.
|
meillo@57
|
148 But, experience shows that building software the first time is
|
meillo@57
|
149 only a small portion of the overall work involved.
|
meillo@45
|
150 Bug fixing, extending, rebuilding of parts \(en maintenance work \(en
|
meillo@57
|
151 soon take a large part of the time spent on a software project.
|
meillo@45
|
152 And of course, the time spent actually using the software.
|
meillo@6
|
153 These processes are highly influenced by the software's quality.
|
meillo@39
|
154 Thus, quality must not be neglected.
|
meillo@45
|
155 However, the problem with quality is that you hardly ``stumble over''
|
meillo@39
|
156 bad quality during the first build,
|
meillo@45
|
157 although this is the time when you should care about good quality most.
|
meillo@6
|
158 .PP
|
meillo@54
|
159 Software design has little to do with the basic function of software \(en
|
meillo@39
|
160 this requirement will get satisfied anyway.
|
meillo@57
|
161 Software design is more about quality aspects.
|
meillo@39
|
162 Good design leads to good quality, bad design to bad quality.
|
meillo@54
|
163 The primary functions of software will be affected modestly by bad quality,
|
meillo@57
|
164 but good quality can provide a lot of additional benefits,
|
meillo@57
|
165 even at places one never expected it.
|
meillo@6
|
166 .PP
|
meillo@45
|
167 The ISO/IEC\|9126-1 standard, part\|1,
|
meillo@6
|
168 .[
|
meillo@44
|
169 iso product quality
|
meillo@6
|
170 .]
|
meillo@57
|
171 defines the quality model as consisting of:
|
meillo@6
|
172 .IP \(bu
|
meillo@6
|
173 .I Functionality
|
meillo@6
|
174 (suitability, accuracy, inter\%operability, security)
|
meillo@6
|
175 .IP \(bu
|
meillo@6
|
176 .I Reliability
|
meillo@6
|
177 (maturity, fault tolerance, recoverability)
|
meillo@6
|
178 .IP \(bu
|
meillo@6
|
179 .I Usability
|
meillo@6
|
180 (understandability, learnability, operability, attractiveness)
|
meillo@6
|
181 .IP \(bu
|
meillo@6
|
182 .I Efficiency
|
meillo@9
|
183 (time behavior, resource utilization)
|
meillo@6
|
184 .IP \(bu
|
meillo@6
|
185 .I Maintainability
|
meillo@23
|
186 (analyzability, changeability, stability, testability)
|
meillo@6
|
187 .IP \(bu
|
meillo@6
|
188 .I Portability
|
meillo@6
|
189 (adaptability, installability, co-existence, replaceability)
|
meillo@6
|
190 .LP
|
meillo@57
|
191 Good design can improve these properties in software;
|
meillo@57
|
192 poorly designed software likely suffers in these areas.
|
meillo@7
|
193 .PP
|
meillo@7
|
194 One further goal of software design is consistency.
|
meillo@57
|
195 Consistency eases understanding, using, and working on things.
|
meillo@57
|
196 Consistent internal structure and consistent external interfaces
|
meillo@39
|
197 can be provided by good design.
|
meillo@7
|
198 .PP
|
meillo@39
|
199 Software should be well designed because good design avoids many
|
meillo@57
|
200 problems during its lifetime.
|
meillo@57
|
201 Also, because good design can offer much additional gain.
|
meillo@57
|
202 Indeed, much effort should be spent on good design to make software more valuable.
|
meillo@57
|
203 The Unix Philosophy provides a way to design software well.
|
meillo@7
|
204 It offers guidelines to achieve good quality and high gain for the effort spent.
|
meillo@0
|
205
|
meillo@0
|
206
|
meillo@48
|
207 .H 1 "The Unix Philosophy
|
meillo@4
|
208 .LP
|
meillo@61
|
209 The origins of the Unix Philosophy have already been introduced.
|
meillo@8
|
210 This chapter explains the philosophy, oriented on Gancarz,
|
meillo@55
|
211 .[
|
meillo@55
|
212 gancarz
|
meillo@55
|
213 unix philosophy
|
meillo@55
|
214 .]
|
meillo@8
|
215 and shows concrete examples of its application.
|
meillo@5
|
216
|
meillo@48
|
217 .H 2 Pipes
|
meillo@4
|
218 .LP
|
meillo@61
|
219 The following examples demonstrate how the Unix Philosophy is applied.
|
meillo@4
|
220 Knowledge of using the Unix shell is assumed.
|
meillo@4
|
221 .PP
|
meillo@4
|
222 Counting the number of files in the current directory:
|
meillo@41
|
223 .DS
|
meillo@4
|
224 ls | wc -l
|
meillo@4
|
225 .DE
|
meillo@4
|
226 The
|
meillo@4
|
227 .CW ls
|
meillo@4
|
228 command lists all files in the current directory, one per line,
|
meillo@4
|
229 and
|
meillo@4
|
230 .CW "wc -l
|
meillo@8
|
231 counts the number of lines.
|
meillo@4
|
232 .PP
|
meillo@8
|
233 Counting the number of files that do not contain ``foo'' in their name:
|
meillo@41
|
234 .DS
|
meillo@4
|
235 ls | grep -v foo | wc -l
|
meillo@4
|
236 .DE
|
meillo@4
|
237 Here, the list of files is filtered by
|
meillo@4
|
238 .CW grep
|
meillo@45
|
239 to remove all lines that contain ``foo''.
|
meillo@45
|
240 The rest equals the previous example.
|
meillo@4
|
241 .PP
|
meillo@61
|
242 Finding the five largest entries in the current directory:
|
meillo@41
|
243 .DS
|
meillo@4
|
244 du -s * | sort -nr | sed 5q
|
meillo@4
|
245 .DE
|
meillo@4
|
246 .CW "du -s *
|
meillo@45
|
247 returns the recursively summed sizes of all files in the current directory
|
meillo@8
|
248 \(en no matter if they are regular files or directories.
|
meillo@4
|
249 .CW "sort -nr
|
meillo@45
|
250 sorts the list numerically in reverse order (descending).
|
meillo@4
|
251 Finally,
|
meillo@4
|
252 .CW "sed 5q
|
meillo@4
|
253 quits after it has printed the fifth line.
|
meillo@4
|
254 .PP
|
meillo@4
|
255 The presented command lines are examples of what Unix people would use
|
meillo@4
|
256 to get the desired output.
|
meillo@61
|
257 There are other ways to get the same output;
|
meillo@61
|
258 it is the user's decision which way to go.
|
meillo@14
|
259 .PP
|
meillo@8
|
260 The examples show that many tasks on a Unix system
|
meillo@4
|
261 are accomplished by combining several small programs.
|
meillo@61
|
262 The connection between the programs is denoted by the pipe operator `|'.
|
meillo@4
|
263 .PP
|
meillo@4
|
264 Pipes, and their extensive and easy use, are one of the great
|
meillo@4
|
265 achievements of the Unix system.
|
meillo@61
|
266 Pipes were possible in earlier operating systems,
|
meillo@61
|
267 but never before have they been such a central part of the concept.
|
meillo@61
|
268 In the early seventies when Doug McIlroy introduced pipes into the
|
meillo@4
|
269 Unix system,
|
meillo@4
|
270 ``it was this concept and notation for linking several programs together
|
meillo@4
|
271 that transformed Unix from a basic file-sharing system to an entirely new way of computing.''
|
meillo@4
|
272 .[
|
meillo@44
|
273 aughenbaugh
|
meillo@44
|
274 unix oral history
|
meillo@45
|
275 .]
|
meillo@4
|
276 .PP
|
meillo@4
|
277 Being able to specify pipelines in an easy way is,
|
meillo@61
|
278 however, not enough by itself;
|
meillo@61
|
279 it is only one half.
|
meillo@4
|
280 The other is the design of the programs that are used in the pipeline.
|
meillo@61
|
281 They need interfaces that allow them to be used in this way.
|
meillo@5
|
282
|
meillo@48
|
283 .H 2 "Interface design
|
meillo@5
|
284 .LP
|
meillo@61
|
285 Unix is, first of all, simple \(en everything is a file.
|
meillo@5
|
286 Files are sequences of bytes, without any special structure.
|
meillo@45
|
287 Programs should be filters, which read a stream of bytes from standard input (stdin)
|
meillo@45
|
288 and write a stream of bytes to standard output (stdout).
|
meillo@8
|
289 If the files \fIare\fP sequences of bytes,
|
meillo@8
|
290 and the programs \fIare\fP filters on byte streams,
|
meillo@45
|
291 then there is exactly one data interface.
|
meillo@45
|
292 Hence it is possible to combine programs in any desired way.
|
meillo@5
|
293 .PP
|
meillo@45
|
294 Even a handful of small programs yields a large set of combinations,
|
meillo@5
|
295 and thus a large set of different functions.
|
meillo@5
|
296 This is leverage!
|
meillo@5
|
297 If the programs are orthogonal to each other \(en the best case \(en
|
meillo@5
|
298 then the set of different functions is greatest.
|
meillo@5
|
299 .PP
|
meillo@61
|
300 Programs can also have a separate control interface
|
meillo@61
|
301 in addition to their data interface.
|
meillo@61
|
302 The control interface is often called the ``user interface'',
|
meillo@11
|
303 because it is usually designed to be used by humans.
|
meillo@61
|
304 The Unix Philosophy discourages the assumption that the user will be human.
|
meillo@11
|
305 Interactive use of software is slow use of software,
|
meillo@11
|
306 because the program waits for user input most of the time.
|
meillo@61
|
307 Interactive software also requires the user to be in front of the computer,
|
meillo@61
|
308 occupying his attention during usage.
|
meillo@11
|
309 .PP
|
meillo@61
|
310 Now, back to the idea of combining several small programs
|
meillo@61
|
311 to perform a more specific function:
|
meillo@61
|
312 If these single tools were all interactive,
|
meillo@11
|
313 how would the user control them?
|
meillo@61
|
314 It is not only a problem to control several programs at once
|
meillo@61
|
315 if they run at the same time;
|
meillo@61
|
316 it is also very inefficient to have to control each program
|
meillo@61
|
317 when they are intended to act in concert.
|
meillo@61
|
318 Hence, the Unix Philosophy discourages designing programs which demand
|
meillo@61
|
319 interactive use.
|
meillo@11
|
320 The behavior of programs should be defined at invocation.
|
meillo@45
|
321 This is done by specifying arguments to the program call
|
meillo@45
|
322 (command line switches).
|
meillo@61
|
323 Gancarz discusses this topic as ``avoid[ing] captive user interfaces''.
|
meillo@46
|
324 .[ [
|
meillo@44
|
325 gancarz unix philosophy
|
meillo@46
|
326 .], page 88 ff.]
|
meillo@11
|
327 .PP
|
meillo@61
|
328 Non-interactive use is also an advantage for testing during development.
|
meillo@61
|
329 Testing interactive programs is much more complicated
|
meillo@61
|
330 than testing non-interactive counterparts.
|
meillo@5
|
331
|
meillo@48
|
332 .H 2 "The toolchest approach
|
meillo@5
|
333 .LP
|
meillo@5
|
334 A toolchest is a set of tools.
|
meillo@61
|
335 Instead of one big tool for all tasks, there are many small tools,
|
meillo@5
|
336 each for one task.
|
meillo@61
|
337 Difficult tasks are solved by combining several small, simple tools.
|
meillo@5
|
338 .PP
|
meillo@11
|
339 The Unix toolchest \fIis\fP a set of small, (mostly) non-interactive programs
|
meillo@11
|
340 that are filters on byte streams.
|
meillo@54
|
341 They are, to a large extent, unrelated in their function.
|
meillo@11
|
342 Hence, the Unix toolchest provides a large set of functions
|
meillo@11
|
343 that can be accessed by combining the programs in the desired way.
|
meillo@11
|
344 .PP
|
meillo@61
|
345 The act of software development benefits from small toolchest programs, too.
|
meillo@61
|
346 Writing small programs is generally easier and less error-prone
|
meillo@61
|
347 than writing large programs.
|
meillo@61
|
348 Hence, writing a large set of small programs is still easier and
|
meillo@61
|
349 less error-prone than writing one large program with all the
|
meillo@61
|
350 functionality included.
|
meillo@61
|
351 If the small programs are combinable, then they offer even an even larger set
|
meillo@61
|
352 of functions than the single monolithic program.
|
meillo@45
|
353 Hence, one gets two advantages out of writing small, combinable programs:
|
meillo@45
|
354 They are easier to write and they offer a greater set of functions through
|
meillo@45
|
355 combination.
|
meillo@5
|
356 .PP
|
meillo@61
|
357 There are also two main drawbacks of the toolchest approach.
|
meillo@45
|
358 First, one simple, standardized interface has to be sufficient.
|
meillo@5
|
359 If one feels the need for more ``logic'' than a stream of bytes,
|
meillo@61
|
360 then a different approach might be required.
|
meillo@61
|
361 Also, a design where a stream of bytes is sufficient,
|
meillo@61
|
362 might not be conceivable.
|
meillo@8
|
363 By becoming more familiar with the ``Unix style of thinking'',
|
meillo@8
|
364 developers will more often and easier find simple designs where
|
meillo@8
|
365 a stream of bytes is a sufficient interface.
|
meillo@8
|
366 .PP
|
meillo@61
|
367 The second drawback of the toolchest approach concerns the users.
|
meillo@61
|
368 A toolchest is often more difficult to use because
|
meillo@61
|
369 it is necessary to become familiar with each tool and
|
meillo@61
|
370 be able to choose and use the right one in any given situation.
|
meillo@61
|
371 Additionally, one needs to know how to combine the tools in a sensible way.
|
meillo@61
|
372 The issue is similar to having a sharp knife \(en
|
meillo@61
|
373 it is a powerful tool in the hand of a master,
|
meillo@61
|
374 but of no value in the hand of an unskilled person.
|
meillo@61
|
375 However, learning single, small tools of a toolchest is often easier than
|
meillo@45
|
376 learning a complex tool.
|
meillo@61
|
377 The user will already have a basic understanding of an as yet unknown tool
|
meillo@45
|
378 if the tools of a toolchest have a common, consistent style.
|
meillo@61
|
379 He will be able to transfer knowledge of one tool to another.
|
meillo@5
|
380 .PP
|
meillo@61
|
381 This second drawback can be removed to a large extent
|
meillo@45
|
382 by adding wrappers around the basic tools.
|
meillo@61
|
383 Novice users do not need to learn several tools if a professional wraps
|
meillo@45
|
384 complete command lines into a higher-level script.
|
meillo@5
|
385 Note that the wrapper script still calls the small tools;
|
meillo@45
|
386 it is just like a skin around them.
|
meillo@61
|
387 No complexity is added this way,
|
meillo@61
|
388 but new programs can be created out of existing one with very little effort.
|
meillo@5
|
389 .PP
|
meillo@5
|
390 A wrapper script for finding the five largest entries in the current directory
|
meillo@61
|
391 might look like this:
|
meillo@41
|
392 .DS
|
meillo@5
|
393 #!/bin/sh
|
meillo@5
|
394 du -s * | sort -nr | sed 5q
|
meillo@5
|
395 .DE
|
meillo@61
|
396 The script itself is just a text file that calls the commands
|
meillo@61
|
397 that a professional user would type in directly.
|
meillo@61
|
398 It is probably beneficial to make the program flexible in regard to
|
meillo@61
|
399 the number of entries it prints:
|
meillo@41
|
400 .DS
|
meillo@8
|
401 #!/bin/sh
|
meillo@8
|
402 num=5
|
meillo@8
|
403 [ $# -eq 1 ] && num="$1"
|
meillo@8
|
404 du -sh * | sort -nr | sed "${num}q"
|
meillo@8
|
405 .DE
|
meillo@61
|
406 This script acts like the one before when called without an argument,
|
meillo@61
|
407 but the user can also specify a numerical argument to define the number
|
meillo@61
|
408 of lines to print.
|
meillo@61
|
409 One can surely imagine even more flexible versions;
|
meillo@61
|
410 however, they will still rely on the external programs
|
meillo@61
|
411 which actually do the work.
|
meillo@5
|
412
|
meillo@48
|
413 .H 2 "A powerful shell
|
meillo@8
|
414 .LP
|
meillo@61
|
415 The Unix shell provides the ability to combine small programs into large ones.
|
meillo@61
|
416 But a powerful shell is a great feature in other ways, too;
|
meillo@61
|
417 for instance, by being scriptable.
|
meillo@61
|
418 Control statements are built into the shell
|
meillo@61
|
419 and the functions are the normal programs of the system.
|
meillo@61
|
420 As the programs are already known,
|
meillo@45
|
421 learning to program in the shell becomes easy.
|
meillo@8
|
422 Using normal programs as functions in the shell programming language
|
meillo@10
|
423 is only possible because they are small and combinable tools in a toolchest style.
|
meillo@8
|
424 .PP
|
meillo@61
|
425 The Unix shell encourages writing small scripts,
|
meillo@61
|
426 by combining existing programs because it is so easy to do.
|
meillo@8
|
427 This is a great step towards automation.
|
meillo@8
|
428 It is wonderful if the effort to automate a task equals the effort
|
meillo@45
|
429 to do the task a second time by hand.
|
meillo@45
|
430 If this holds,
|
meillo@45
|
431 then the user will be happy to automate everything he does more than once.
|
meillo@8
|
432 .PP
|
meillo@8
|
433 Small programs that do one job well, standardized interfaces between them,
|
meillo@61
|
434 a mechanism to combine parts to larger parts, and an easy way to automate tasks
|
meillo@61
|
435 will inevitably produce software leverage,
|
meillo@61
|
436 achieving multiple times the benefit of the initial investment.
|
meillo@10
|
437 .PP
|
meillo@10
|
438 The shell also encourages rapid prototyping.
|
meillo@10
|
439 Many well known programs started as quickly hacked shell scripts,
|
meillo@61
|
440 and turned into ``real'' programs later written in C.
|
meillo@61
|
441 Building a prototype first is a way to avoid the biggest problems
|
meillo@10
|
442 in application development.
|
meillo@45
|
443 Fred Brooks explains in ``No Silver Bullet'':
|
meillo@10
|
444 .[
|
meillo@44
|
445 brooks
|
meillo@44
|
446 no silver bullet
|
meillo@10
|
447 .]
|
meillo@10
|
448 .QP
|
meillo@10
|
449 The hardest single part of building a software system is deciding precisely what to build.
|
meillo@10
|
450 No other part of the conceptual work is so difficult as establishing the detailed
|
meillo@10
|
451 technical requirements, [...].
|
meillo@10
|
452 No other part of the work so cripples the resulting system if done wrong.
|
meillo@10
|
453 No other part is more difficult to rectify later.
|
meillo@10
|
454 .PP
|
meillo@45
|
455 Writing a prototype is a great method for becoming familiar with the requirements
|
meillo@45
|
456 and to run into real problems early.
|
meillo@47
|
457 .[ [
|
meillo@47
|
458 gancarz
|
meillo@47
|
459 unix philosophy
|
meillo@47
|
460 .], page 28 f.]
|
meillo@45
|
461 .PP
|
meillo@54
|
462 Prototyping is often seen as a first step in building software.
|
meillo@10
|
463 This is, of course, good.
|
meillo@10
|
464 However, the Unix Philosophy has an \fIadditional\fP perspective on prototyping:
|
meillo@61
|
465 After having built the prototype, one might notice that the prototype is already
|
meillo@10
|
466 \fIgood enough\fP.
|
meillo@61
|
467 Hence, no reimplementation in a more sophisticated programming language
|
meillo@45
|
468 might be of need, at least for the moment.
|
meillo@23
|
469 Maybe later, it might be necessary to rewrite the software, but not now.
|
meillo@45
|
470 By delaying further work, one keeps the flexibility to react on
|
meillo@10
|
471 changing requirements.
|
meillo@10
|
472 Software parts that are not written will not miss the requirements.
|
meillo@61
|
473 Well known is Gordon Bell's classic saying:
|
meillo@61
|
474 ``The cheapest, fastest, and most reliable components are those
|
meillo@61
|
475 that aren't there.''
|
meillo@61
|
476 .\" FIXME: ref?
|
meillo@10
|
477
|
meillo@48
|
478 .H 2 "Worse is better
|
meillo@10
|
479 .LP
|
meillo@45
|
480 The Unix Philosophy aims for the 90% solution;
|
meillo@10
|
481 others call it the ``Worse is better'' approach.
|
meillo@47
|
482 Experience from real life projects shows:
|
meillo@10
|
483 .PP
|
meillo@61
|
484 (1) It is almost impossible to define the
|
meillo@10
|
485 requirements completely and correctly the first time.
|
meillo@45
|
486 Hence one should not try to; one will fail anyway.
|
meillo@45
|
487 .PP
|
meillo@45
|
488 (2) Requirements change during time.
|
meillo@10
|
489 Hence it is best to delay requirement-based design decisions as long as possible.
|
meillo@61
|
490 Software should be small and flexible as long as possible in order
|
meillo@61
|
491 to react to changing requirements.
|
meillo@61
|
492 Shell scripts, for example, are more easily adjusted than C programs.
|
meillo@45
|
493 .PP
|
meillo@45
|
494 (3) Maintenance work is hard work.
|
meillo@45
|
495 Hence, one should keep the amount of code as small as possible;
|
meillo@61
|
496 it should only fulfill the \fIcurrent\fP requirements.
|
meillo@61
|
497 Software parts that will be written in the future
|
meillo@61
|
498 do not need maintenance until that time.
|
meillo@10
|
499 .PP
|
meillo@47
|
500 See Brooks' ``The Mythical Man-Month'' for reference.
|
meillo@47
|
501 .[ [
|
meillo@47
|
502 brooks
|
meillo@47
|
503 mythical man-month
|
meillo@47
|
504 .], page 115 ff.]
|
meillo@47
|
505 .PP
|
meillo@10
|
506 Starting with a prototype in a scripting language has several advantages:
|
meillo@10
|
507 .IP \(bu
|
meillo@10
|
508 As the initial effort is low, one will likely start right away.
|
meillo@10
|
509 .IP \(bu
|
meillo@61
|
510 Real requirements can be identified quickly since working parts are
|
meillo@61
|
511 available sooner.
|
meillo@10
|
512 .IP \(bu
|
meillo@54
|
513 When software is usable and valuable, it gets used, and thus tested.
|
meillo@61
|
514 This ensures that problems will be found in the early stages of development.
|
meillo@10
|
515 .IP \(bu
|
meillo@61
|
516 The prototype might be enough for the moment;
|
meillo@61
|
517 thus, further work can be delayed until a time
|
meillo@61
|
518 when one knows about the requirements and problems more thoroughly.
|
meillo@10
|
519 .IP \(bu
|
meillo@61
|
520 Implementing only the parts that are actually needed at the moment
|
meillo@61
|
521 introduces less programming and maintenance work.
|
meillo@10
|
522 .IP \(bu
|
meillo@61
|
523 If the situation changes such that the software is not needed anymore,
|
meillo@61
|
524 then less effort was spent on the project than it would have been
|
meillo@61
|
525 if a different approach had been taken.
|
meillo@10
|
526
|
meillo@48
|
527 .H 2 "Upgrowth and survival of software
|
meillo@11
|
528 .LP
|
meillo@61
|
529 So far, \fIwriting\fP or \fIbuilding\fP software has been discussed.
|
meillo@61
|
530 Although ``writing'' and ``building'' are just verbs,
|
meillo@61
|
531 they do imply a specific view on the work process they describe.
|
meillo@61
|
532 A better verb would be to \fI``grow''\fP.
|
meillo@12
|
533 Creating software in the sense of the Unix Philosophy is an incremental process.
|
meillo@61
|
534 It starts with an initial prototype, which evolves as requirements change.
|
meillo@12
|
535 A quickly hacked shell script might become a large, sophisticated,
|
meillo@13
|
536 compiled program this way.
|
meillo@13
|
537 Its lifetime begins with the initial prototype and ends when the software is not used anymore.
|
meillo@61
|
538 While alive, it will be extended, rearranged, rebuilt.
|
meillo@12
|
539 Growing software matches the view that ``software is never finished. It is only released.''
|
meillo@46
|
540 .[ [
|
meillo@44
|
541 gancarz
|
meillo@44
|
542 unix philosophy
|
meillo@46
|
543 .], page 26]
|
meillo@12
|
544 .PP
|
meillo@13
|
545 Software can be seen as being controlled by evolutionary processes.
|
meillo@13
|
546 Successful software is software that is used by many for a long time.
|
meillo@61
|
547 This implies that the software is necessary, useful, and better than the alternatives.
|
meillo@61
|
548 Darwin describes ``the survival of the fittest.''
|
meillo@12
|
549 .[
|
meillo@44
|
550 darwin
|
meillo@44
|
551 origin of species
|
meillo@12
|
552 .]
|
meillo@61
|
553 In relation to software, the most successful software is the fittest;
|
meillo@61
|
554 the one that survives.
|
meillo@13
|
555 (This may be at the level of one creature, or at the level of one species.)
|
meillo@13
|
556 The fitness of software is affected mainly by four properties:
|
meillo@15
|
557 portability of code, portability of data, range of usability, and reusability of parts.
|
meillo@13
|
558 .PP
|
meillo@15
|
559 (1)
|
meillo@61
|
560 .I "``Portability of code''
|
meillo@61
|
561 means using high-level programming languages,
|
meillo@13
|
562 sticking to the standard,
|
meillo@47
|
563 .[ [
|
meillo@47
|
564 kernighan pike
|
meillo@47
|
565 practice of programming
|
meillo@47
|
566 .], chapter\|8]
|
meillo@13
|
567 and avoiding optimizations that introduce dependencies on specific hardware.
|
meillo@61
|
568 Hardware has a much shorter lifespan than software.
|
meillo@61
|
569 By chaining software to specific hardware,
|
meillo@61
|
570 its lifetime is limited to that of this hardware.
|
meillo@13
|
571 In contrast, software should be easy to port \(en
|
meillo@23
|
572 adaptation is the key to success.
|
meillo@13
|
573 .PP
|
meillo@15
|
574 (2)
|
meillo@61
|
575 .I "``Portability of data''
|
meillo@15
|
576 is best achieved by avoiding binary representations
|
meillo@61
|
577 to store data, since binary representations differ from machine to machine.
|
meillo@23
|
578 Textual representation is favored.
|
meillo@61
|
579 Historically, \s-1ASCII\s0 was the character set of choice;
|
meillo@61
|
580 for the future, \s-1UTF\s0-8 might be the better way forward.
|
meillo@13
|
581 Important is that it is a plain text representation in a
|
meillo@61
|
582 very common character set encoding.
|
meillo@13
|
583 Apart from being able to transfer data between machines,
|
meillo@61
|
584 readable data has the great advantage that humans are able to directly
|
meillo@45
|
585 read and edit it with text editors and other tools from the Unix toolchest.
|
meillo@47
|
586 .[ [
|
meillo@47
|
587 gancarz
|
meillo@47
|
588 unix philosophy
|
meillo@47
|
589 .], page 56 ff.]
|
meillo@13
|
590 .PP
|
meillo@15
|
591 (3)
|
meillo@15
|
592 A large
|
meillo@61
|
593 .I "``range of usability''
|
meillo@23
|
594 ensures good adaptation, and thus good survival.
|
meillo@61
|
595 It is a special distinction when software becomes used in fields of endeavor,
|
meillo@61
|
596 the original authors never imagined.
|
meillo@13
|
597 Software that solves problems in a general way will likely be used
|
meillo@45
|
598 for many kinds of similar problems.
|
meillo@45
|
599 Being too specific limits the range of usability.
|
meillo@13
|
600 Requirements change through time, thus use cases change or even vanish.
|
meillo@61
|
601 As a good example of this point,
|
meillo@13
|
602 Allman identifies flexibility to be one major reason for sendmail's success:
|
meillo@13
|
603 .[
|
meillo@44
|
604 allman
|
meillo@44
|
605 sendmail
|
meillo@13
|
606 .]
|
meillo@13
|
607 .QP
|
meillo@13
|
608 Second, I limited myself to the routing function [...].
|
meillo@13
|
609 This was a departure from the dominant thought of the time, [...].
|
meillo@13
|
610 .QP
|
meillo@45
|
611 Third, the sendmail configuration file was flexible enough to adapt
|
meillo@13
|
612 to a rapidly changing world [...].
|
meillo@12
|
613 .LP
|
meillo@45
|
614 Successful software adapts itself to the changing world.
|
meillo@13
|
615 .PP
|
meillo@15
|
616 (4)
|
meillo@61
|
617 .I "``Reusability of parts''
|
meillo@61
|
618 goes one step further.
|
meillo@61
|
619 Software may become obsolete and completely lose its field of action,
|
meillo@61
|
620 but the constituent parts of the software may be general and independent enough
|
meillo@13
|
621 to survive this death.
|
meillo@54
|
622 If software is built by combining small independent programs,
|
meillo@45
|
623 then these parts are readily available for reuse.
|
meillo@61
|
624 Who cares that the large program is a failure,
|
meillo@61
|
625 if parts of it become successful instead?
|
meillo@10
|
626
|
meillo@48
|
627 .H 2 "Summary
|
meillo@0
|
628 .LP
|
meillo@61
|
629 This chapter explained ideas central to the Unix Philosophy.
|
meillo@45
|
630 For each of the ideas, the advantages they introduce were explained.
|
meillo@61
|
631 The Unix Philosophy is a set of guidelines that help in the design of
|
meillo@61
|
632 more valuable software.
|
meillo@61
|
633 From the viewpoint of a software developer or software designer,
|
meillo@61
|
634 the Unix Philosophy provides answers to many software design problems.
|
meillo@14
|
635 .PP
|
meillo@61
|
636 The various ideas comprising the Unix Philosophy are very interweaved
|
meillo@14
|
637 and can hardly be applied independently.
|
meillo@61
|
638 The most important messages are:
|
meillo@45
|
639 .I "``Keep it simple!''" ,
|
meillo@14
|
640 .I "``Do one thing well!''" ,
|
meillo@14
|
641 and
|
meillo@14
|
642 .I "``Use software leverage!''
|
meillo@0
|
643
|
meillo@8
|
644
|
meillo@8
|
645
|
meillo@48
|
646 .H 1 "Case study: \s-1MH\s0
|
meillo@18
|
647 .LP
|
meillo@30
|
648 The previous chapter introduced and explained the Unix Philosophy
|
meillo@18
|
649 from a general point of view.
|
meillo@61
|
650 The driving force was that of the guidelines;
|
meillo@61
|
651 references to existing software were given only sparsely.
|
meillo@18
|
652 In this and the next chapter, concrete software will be
|
meillo@18
|
653 the driving force in the discussion.
|
meillo@18
|
654 .PP
|
meillo@23
|
655 This first case study is about the mail user agents (\s-1MUA\s0)
|
meillo@54
|
656 \s-1MH\s0 (``mail handler'') and its descendant \fInmh\fP
|
meillo@23
|
657 (``new mail handler'').
|
meillo@47
|
658 .[
|
meillo@47
|
659 nmh website
|
meillo@47
|
660 .]
|
meillo@23
|
661 \s-1MUA\s0s provide functions to read, compose, and organize mail,
|
meillo@45
|
662 but (ideally) not to transfer it.
|
meillo@45
|
663 In this document, the name \s-1MH\s0 will be used to include nmh.
|
meillo@19
|
664 A distinction will only be made if differences between
|
meillo@45
|
665 \s-1MH\s0 and nmh are described.
|
meillo@18
|
666
|
meillo@0
|
667
|
meillo@48
|
668 .H 2 "Historical background
|
meillo@0
|
669 .LP
|
meillo@61
|
670 Electronic mail was available in Unix from a very early stage.
|
meillo@30
|
671 The first \s-1MUA\s0 on Unix was \f(CWmail\fP,
|
meillo@30
|
672 which was already present in the First Edition.
|
meillo@46
|
673 .[ [
|
meillo@44
|
674 salus
|
meillo@44
|
675 quarter century of unix
|
meillo@46
|
676 .], page 41 f.]
|
meillo@45
|
677 It was a small program that either printed the user's mailbox file
|
meillo@54
|
678 or appended text to someone else's mailbox file,
|
meillo@19
|
679 depending on the command line arguments.
|
meillo@19
|
680 .[
|
meillo@44
|
681 manual mail(1)
|
meillo@19
|
682 .]
|
meillo@19
|
683 It was a program that did one job well.
|
meillo@23
|
684 This job was emailing, which was very simple then.
|
meillo@19
|
685 .PP
|
meillo@23
|
686 Later, emailing became more powerful, and thus more complex.
|
meillo@19
|
687 The simple \f(CWmail\fP, which knew nothing of subjects,
|
meillo@19
|
688 independent handling of single messages,
|
meillo@61
|
689 and long-term email storage, was not powerful enough anymore.
|
meillo@61
|
690 In 1978 at Berkeley, Kurt Shoens wrote \fIMail\fP (with a capital `M')
|
meillo@45
|
691 to provide additional functions for emailing.
|
meillo@61
|
692 Mail was still one program, but was large and did several jobs.
|
meillo@61
|
693 Its user interface was modeled after \fIed\fP.
|
meillo@61
|
694 Ed is designed for humans, but is still scriptable.
|
meillo@61
|
695 \fImailx\fP is the adaptation of Berkeley Mail for System V.
|
meillo@19
|
696 .[
|
meillo@44
|
697 ritter
|
meillo@44
|
698 mailx history
|
meillo@19
|
699 .]
|
meillo@61
|
700 Elm, pine, mutt, and a slew of graphical \s-1MUA\s0s
|
meillo@61
|
701 followed Mail's direction:
|
meillo@61
|
702 large, monolithic programs which included all emailing functions.
|
meillo@19
|
703 .PP
|
meillo@23
|
704 A different way was taken by the people of \s-1RAND\s0 Corporation.
|
meillo@61
|
705 Initially, they also had used a monolithic mail system
|
meillo@30
|
706 called \s-1MS\s0 (for ``mail system'').
|
meillo@19
|
707 But in 1977, Stockton Gaines and Norman Shapiro
|
meillo@61
|
708 came up with a proposal for a new email system concept \(en
|
meillo@45
|
709 one that honored the Unix Philosophy.
|
meillo@19
|
710 The concept was implemented by Bruce Borden in 1978 and 1979.
|
meillo@19
|
711 This was the birth of \s-1MH\s0 \(en the ``mail handler''.
|
meillo@18
|
712 .PP
|
meillo@18
|
713 Since then, \s-1RAND\s0, the University of California at Irvine and
|
meillo@19
|
714 at Berkeley, and several others have contributed to the software.
|
meillo@18
|
715 However, it's core concepts remained the same.
|
meillo@23
|
716 In the late 90s, when development of \s-1MH\s0 slowed down,
|
meillo@19
|
717 Richard Coleman started with \fInmh\fP, the new mail handler.
|
meillo@61
|
718 His goal was to improve \s-1MH\s0 especially in regard to
|
meillo@23
|
719 the requirements of modern emailing.
|
meillo@19
|
720 Today, nmh is developed by various people on the Internet.
|
meillo@18
|
721 .[
|
meillo@44
|
722 ware
|
meillo@44
|
723 rand history
|
meillo@18
|
724 .]
|
meillo@18
|
725 .[
|
meillo@44
|
726 peek
|
meillo@44
|
727 mh
|
meillo@18
|
728 .]
|
meillo@0
|
729
|
meillo@48
|
730 .H 2 "Contrasts to monolithic mail systems
|
meillo@0
|
731 .LP
|
meillo@19
|
732 All \s-1MUA\s0s are monolithic, except \s-1MH\s0.
|
meillo@61
|
733 Although some very little known toolchest \s-1MUA\s0s might also exist,
|
meillo@61
|
734 this statement reflects the situation pretty well.
|
meillo@19
|
735 .PP
|
meillo@30
|
736 Monolithic \s-1MUA\s0s gather all their functions in one program.
|
meillo@30
|
737 In contrast, \s-1MH\s0 is a toolchest of many small tools \(en one for each job.
|
meillo@23
|
738 Following is a list of important programs of \s-1MH\s0's toolchest
|
meillo@30
|
739 and their function.
|
meillo@61
|
740 It gives an indication of what the toolchest looks like.
|
meillo@19
|
741 .IP \(bu
|
meillo@19
|
742 .CW inc :
|
meillo@30
|
743 incorporate new mail (this is how mail enters the system)
|
meillo@19
|
744 .IP \(bu
|
meillo@19
|
745 .CW scan :
|
meillo@19
|
746 list messages in folder
|
meillo@19
|
747 .IP \(bu
|
meillo@19
|
748 .CW show :
|
meillo@19
|
749 show message
|
meillo@19
|
750 .IP \(bu
|
meillo@19
|
751 .CW next\fR/\fPprev :
|
meillo@19
|
752 show next/previous message
|
meillo@19
|
753 .IP \(bu
|
meillo@19
|
754 .CW folder :
|
meillo@19
|
755 change current folder
|
meillo@19
|
756 .IP \(bu
|
meillo@19
|
757 .CW refile :
|
meillo@45
|
758 refile message into different folder
|
meillo@19
|
759 .IP \(bu
|
meillo@19
|
760 .CW rmm :
|
meillo@19
|
761 remove message
|
meillo@19
|
762 .IP \(bu
|
meillo@19
|
763 .CW comp :
|
meillo@45
|
764 compose new message
|
meillo@19
|
765 .IP \(bu
|
meillo@19
|
766 .CW repl :
|
meillo@45
|
767 reply to message
|
meillo@19
|
768 .IP \(bu
|
meillo@19
|
769 .CW forw :
|
meillo@45
|
770 forward message
|
meillo@19
|
771 .IP \(bu
|
meillo@19
|
772 .CW send :
|
meillo@45
|
773 send prepared message (this is how mail leaves the system)
|
meillo@0
|
774 .LP
|
meillo@19
|
775 \s-1MH\s0 has no special user interface like monolithic \s-1MUA\s0s have.
|
meillo@61
|
776 The user does not leave the shell to run \s-1MH\s0;
|
meillo@45
|
777 instead he uses the various \s-1MH\s0 programs within the shell.
|
meillo@23
|
778 Using a monolithic program with a captive user interface
|
meillo@23
|
779 means ``entering'' the program, using it, and ``exiting'' the program.
|
meillo@23
|
780 Using toolchests like \s-1MH\s0 means running programs,
|
meillo@45
|
781 alone or in combination with others, also from other toolchests,
|
meillo@23
|
782 without leaving the shell.
|
meillo@30
|
783
|
meillo@48
|
784 .H 2 "Data storage
|
meillo@30
|
785 .LP
|
meillo@61
|
786 \s-1MH\s0's mail storage consists of a hierarchy under the user's
|
meillo@34
|
787 \s-1MH\s0 directory (usually \f(CW$HOME/Mail\fP),
|
meillo@34
|
788 where mail folders are directories and mail messages are text files
|
meillo@34
|
789 within them.
|
meillo@34
|
790 Each mail folder contains a file \f(CW.mh_sequences\fP which lists
|
meillo@45
|
791 the public message sequences of that folder,
|
meillo@61
|
792 for instance, the \fIunseen\fP sequence for new messages.
|
meillo@34
|
793 Mail messages are text files located in a mail folder.
|
meillo@61
|
794 The files contain the messages as they were received,
|
meillo@61
|
795 and they are named by ascending numbers in each folder.
|
meillo@19
|
796 .PP
|
meillo@30
|
797 This mailbox format is called ``\s-1MH\s0'' after the \s-1MUA\s0.
|
meillo@30
|
798 Alternatives are \fImbox\fP and \fImaildir\fP.
|
meillo@61
|
799 In the mbox format, all messages are stored within one file.
|
meillo@30
|
800 This was a good solution in the early days, when messages
|
meillo@61
|
801 were only a few lines of text deleted within a short period of time.
|
meillo@61
|
802 Today, with single messages often including several megabytes
|
meillo@61
|
803 of attachments, this is a bad solution.
|
meillo@30
|
804 Another disadvantage of the mbox format is that it is
|
meillo@30
|
805 more difficult to write tools that work on mail messages,
|
meillo@30
|
806 because it is always necessary to first find and extract
|
meillo@30
|
807 the relevant message in the mbox file.
|
meillo@45
|
808 With the \s-1MH\s0 mailbox format, each message is a separate file.
|
meillo@30
|
809 Also, the problem of concurrent access to one mailbox is
|
meillo@30
|
810 reduced to the problem of concurrent access to one message.
|
meillo@45
|
811 The maildir format is generally similar to the \s-1MH\s0 format,
|
meillo@30
|
812 but modified towards guaranteed reliability.
|
meillo@30
|
813 This involves some complexity, unfortunately.
|
meillo@34
|
814 .PP
|
meillo@34
|
815 Working with \s-1MH\s0's toolchest on mailboxes is much like
|
meillo@34
|
816 working with Unix' toolchest on directory trees:
|
meillo@34
|
817 \f(CWscan\fP is like \f(CWls\fP,
|
meillo@34
|
818 \f(CWshow\fP is like \f(CWcat\fP,
|
meillo@34
|
819 \f(CWfolder\fP is like \f(CWcd\fP and \f(CWpwd\fP,
|
meillo@34
|
820 \f(CWrefile\fP is like \f(CWmv\fP,
|
meillo@34
|
821 and \f(CWrmm\fP is like \f(CWrm\fP.
|
meillo@34
|
822 .PP
|
meillo@61
|
823 \s-1MH\s0 extends the context of processes in Unix by two more items
|
meillo@45
|
824 for its tools:
|
meillo@34
|
825 .IP \(bu
|
meillo@34
|
826 The current mail folder, which is similar to the current working directory.
|
meillo@34
|
827 For mail folders, \f(CWfolder\fP provides the corresponding functionality
|
meillo@34
|
828 of \f(CWcd\fP and \f(CWpwd\fP for directories.
|
meillo@34
|
829 .IP \(bu
|
meillo@34
|
830 Sequences, which are named sets of messages in a mail folder.
|
meillo@34
|
831 The current message, relative to a mail folder, is a special sequence.
|
meillo@34
|
832 It enables commands like \f(CWnext\fP and \f(CWprev\fP.
|
meillo@34
|
833 .LP
|
meillo@61
|
834 In contrast to the general process context in Unix,
|
meillo@61
|
835 which is maintained by the kernel,
|
meillo@45
|
836 \s-1MH\s0's context must be maintained by the tools themselves.
|
meillo@45
|
837 Usually there is one context per user, which resides in his
|
meillo@45
|
838 \f(CWcontext\fP file in the \s-1MH\s0 directory,
|
meillo@45
|
839 but a user can have several contexts, too.
|
meillo@45
|
840 Public sequences are an exception, as they belong to a mail folder,
|
meillo@45
|
841 and reside in the \f(CW.mh_sequences\fP file there.
|
meillo@34
|
842 .[
|
meillo@44
|
843 man page mh-profile mh-sequence
|
meillo@34
|
844 .]
|
meillo@20
|
845
|
meillo@48
|
846 .H 2 "Discussion of the design
|
meillo@0
|
847 .LP
|
meillo@45
|
848 This section discusses \s-1MH\s0 in regard to the tenets
|
meillo@45
|
849 of the Unix Philosophy that Gancarz identified.
|
meillo@20
|
850
|
meillo@20
|
851 .PP
|
meillo@33
|
852 .B "Small is beautiful
|
meillo@20
|
853 and
|
meillo@33
|
854 .B "do one thing well
|
meillo@20
|
855 are two design goals that are directly visible in \s-1MH\s0.
|
meillo@61
|
856 Gancarz actually uses \s-1MH\s0 in his book as example under the
|
meillo@45
|
857 headline ``Making \s-1UNIX\s0 Do One Thing Well'':
|
meillo@46
|
858 .[ [
|
meillo@44
|
859 gancarz
|
meillo@44
|
860 unix philosophy
|
meillo@46
|
861 .], page 125 ff.]
|
meillo@20
|
862 .QP
|
meillo@20
|
863 [\s-1MH\s0] consists of a series of programs which
|
meillo@20
|
864 when combined give the user an enormous ability
|
meillo@20
|
865 to manipulate electronic mail messages.
|
meillo@20
|
866 A complex application, it shows that not only is it
|
meillo@20
|
867 possible to build large applications from smaller
|
meillo@20
|
868 components, but also that such designs are actually preferable.
|
meillo@20
|
869 .LP
|
meillo@45
|
870 The various programs of \s-1MH\s0 were relatively easy to write,
|
meillo@61
|
871 because each one was small, limited to one function,
|
meillo@61
|
872 and had clear boundaries.
|
meillo@61
|
873 For the same reasons, they are also easy to maintain.
|
meillo@61
|
874 Further more, the system can easily get extended:
|
meillo@61
|
875 One only needs to place a new program into the toolchest.
|
meillo@61
|
876 This was done when \s-1MIME\s0 support was added
|
meillo@20
|
877 (e.g. \f(CWmhbuild\fP).
|
meillo@61
|
878 Also, different programs can exist to do basically the same job
|
meillo@20
|
879 in different ways (e.g. in nmh: \f(CWshow\fP and \f(CWmhshow\fP).
|
meillo@45
|
880 .PP
|
meillo@61
|
881 If someone needs a mail system with some additional
|
meillo@61
|
882 functionality that is not available anywhere yet,
|
meillo@61
|
883 it is beneficial to expand a toolchest system like \s-1MH\s0.
|
meillo@45
|
884 There he can add new functionality by simply adding additional
|
meillo@61
|
885 programs to the toolchest;
|
meillo@61
|
886 he does not risk to break existing functionality by doing so.
|
meillo@20
|
887
|
meillo@20
|
888 .PP
|
meillo@61
|
889 .B "Store data in flat text files" ;
|
meillo@61
|
890 this principle was followed by \s-1MH\s0.
|
meillo@34
|
891 This is not surprising, because email messages are already plain text.
|
meillo@34
|
892 \s-1MH\s0 stores the messages as it receives them,
|
meillo@61
|
893 thus any other tool that works on \s-1RFC\s0\|2822 compliant mail
|
meillo@61
|
894 messages can operate
|
meillo@34
|
895 on the messages in an \s-1MH\s0 mailbox.
|
meillo@61
|
896 All other files \s-1MH\s0 uses are plain text as well.
|
meillo@34
|
897 It is therefore possible and encouraged to use the text processing
|
meillo@34
|
898 tools of Unix' toolchest to extend \s-1MH\s0's toolchest.
|
meillo@20
|
899
|
meillo@20
|
900 .PP
|
meillo@33
|
901 .B "Avoid captive user interfaces" .
|
meillo@19
|
902 \s-1MH\s0 is perfectly suited for non-interactive use.
|
meillo@61
|
903 It offers all functions directly, without captive user interfaces.
|
meillo@61
|
904 If users want a graphical user interface,
|
meillo@53
|
905 they can have it with \fIxmh\fP, \fIexmh\fP,
|
meillo@53
|
906 or with the Emacs interface \fImh-e\fP.
|
meillo@53
|
907 These are frontends for the \s-1MH\s0 toolchest.
|
meillo@61
|
908 This means all email-related work is still done by \s-1MH\s0 tools,
|
meillo@45
|
909 but the frontend calls the appropriate commands when the user
|
meillo@53
|
910 clicks on buttons or pushes a key.
|
meillo@45
|
911 .PP
|
meillo@61
|
912 Providing additional user interfaces in form of frontends is a good
|
meillo@19
|
913 approach, because it does not limit the power of the backend itself.
|
meillo@61
|
914 The frontend will only be able to make a subset of the
|
meillo@61
|
915 backend's power and flexibility available to the user,
|
meillo@61
|
916 but if it is a separate program,
|
meillo@20
|
917 then the missing parts can still be accessed at the backend directly.
|
meillo@61
|
918 If it is integrated, then this will be much more difficult.
|
meillo@61
|
919 An additional advantage is the ability to have different frontends
|
meillo@45
|
920 to the same backend.
|
meillo@19
|
921
|
meillo@19
|
922 .PP
|
meillo@33
|
923 .B "Choose portability over efficiency
|
meillo@20
|
924 and
|
meillo@33
|
925 .B "use shell scripts to increase leverage and portability" .
|
meillo@20
|
926 These two tenets are indirectly, but nicely, demonstrated by
|
meillo@30
|
927 Bolsky and Korn in their book about the Korn Shell.
|
meillo@20
|
928 .[
|
meillo@44
|
929 bolsky korn
|
meillo@44
|
930 korn shell
|
meillo@20
|
931 .]
|
meillo@45
|
932 Chapter\|18 of the book shows a basic implementation
|
meillo@20
|
933 of a subset of \s-1MH\s0 in ksh scripts.
|
meillo@61
|
934 This is just a demonstration, but a brilliant one.
|
meillo@20
|
935 It shows how quickly one can implement such a prototype with shell scripts,
|
meillo@20
|
936 and how readable they are.
|
meillo@61
|
937 The implementation in scripting language may not be very fast,
|
meillo@61
|
938 but it can be fast enough, and this is all that matters.
|
meillo@20
|
939 By having the code in an interpreted language, like the shell,
|
meillo@61
|
940 portability becomes a minor issue if we assume the interpreter
|
meillo@20
|
941 to be widespread.
|
meillo@45
|
942 .PP
|
meillo@20
|
943 This demonstration also shows how easy it is to create single programs
|
meillo@61
|
944 of toolchest software.
|
meillo@61
|
945 Eight tools (two of them having multiple names) and 16 functions
|
meillo@45
|
946 with supporting code are presented to the reader.
|
meillo@45
|
947 The tools comprise less than 40 lines of ksh each,
|
meillo@30
|
948 in total about 200 lines.
|
meillo@45
|
949 The functions comprise less than 80 lines of ksh each,
|
meillo@30
|
950 in total about 450 lines.
|
meillo@20
|
951 Such small software is easy to write, easy to understand,
|
meillo@20
|
952 and thus easy to maintain.
|
meillo@61
|
953 A toolchest improves one's ability to only write some parts of a
|
meillo@61
|
954 program while still creating a working result.
|
meillo@45
|
955 Expanding the toolchest, even without global changes,
|
meillo@45
|
956 will likely be possible.
|
meillo@20
|
957
|
meillo@20
|
958 .PP
|
meillo@33
|
959 .B "Use software leverage to your advantage
|
meillo@20
|
960 and the lesser tenet
|
meillo@33
|
961 .B "allow the user to tailor the environment
|
meillo@20
|
962 are ideally followed in the design of \s-1MH\s0.
|
meillo@21
|
963 Tailoring the environment is heavily encouraged by the ability to
|
meillo@30
|
964 directly define default options to programs.
|
meillo@30
|
965 It is even possible to define different default options
|
meillo@45
|
966 depending on the name under which a program is called.
|
meillo@45
|
967 Software leverage is heavily encouraged by the ease of
|
meillo@45
|
968 creating shell scripts that run a specific command line,
|
meillo@30
|
969 built of several \s-1MH\s0 programs.
|
meillo@61
|
970 There are few pieces of software that encourages users to tailor their
|
meillo@61
|
971 environment and to leverage the use of the software like \s-1MH\s0.
|
meillo@45
|
972 .PP
|
meillo@61
|
973 Just to cite one example:
|
meillo@23
|
974 One might prefer a different listing format for the \f(CWscan\fP
|
meillo@21
|
975 program.
|
meillo@30
|
976 It is possible to take one of the distributed format files
|
meillo@21
|
977 or to write one yourself.
|
meillo@21
|
978 To use the format as default for \f(CWscan\fP, a single line,
|
meillo@21
|
979 reading
|
meillo@21
|
980 .DS
|
meillo@21
|
981 scan: -form FORMATFILE
|
meillo@21
|
982 .DE
|
meillo@21
|
983 must be added to \f(CW.mh_profile\fP.
|
meillo@61
|
984 If one wants this alternative format available as an additional command,
|
meillo@61
|
985 instead of changing the default, he just needs to create a link to
|
meillo@23
|
986 \f(CWscan\fP, for instance titled \f(CWscan2\fP.
|
meillo@21
|
987 The line in \f(CW.mh_profile\fP would then start with \f(CWscan2\fP,
|
meillo@61
|
988 as the option should only be in effect for a program that is invoked as
|
meillo@21
|
989 \f(CWscan2\fP.
|
meillo@20
|
990
|
meillo@20
|
991 .PP
|
meillo@33
|
992 .B "Make every program a filter
|
meillo@61
|
993 is hard to find implemented in \s-1MH\s0.
|
meillo@61
|
994 The reason is that most of \s-1MH\s0's tools provide
|
meillo@45
|
995 basic file system operations for mailboxes.
|
meillo@61
|
996 It is for the same reason because that \f(CWls\fP, \f(CWcp\fP, \f(CWmv\fP,
|
meillo@45
|
997 and \f(CWrm\fP aren't filters neither.
|
meillo@61
|
998 \s-1MH\s0 does not provide many filters itself,
|
meillo@61
|
999 but it provides a basis upon which to write filters.
|
meillo@45
|
1000 An example would be a mail text highlighter,
|
meillo@61
|
1001 a program that makes use of a color terminal to display header lines,
|
meillo@61
|
1002 quotations, and signatures in distinct colors.
|
meillo@45
|
1003 The author's version of such a program is an awk script with 25 lines.
|
meillo@21
|
1004
|
meillo@21
|
1005 .PP
|
meillo@33
|
1006 .B "Build a prototype as soon as possible
|
meillo@21
|
1007 was again well followed by \s-1MH\s0.
|
meillo@61
|
1008 This tenet, of course, focuses on early development, which is a
|
meillo@21
|
1009 long time ago for \s-1MH\s0.
|
meillo@21
|
1010 But without following this guideline at the very beginning,
|
meillo@23
|
1011 Bruce Borden may have not convinced the management of \s-1RAND\s0
|
meillo@23
|
1012 to ever create \s-1MH\s0.
|
meillo@23
|
1013 In Bruce' own words:
|
meillo@46
|
1014 .[ [
|
meillo@44
|
1015 ware rand history
|
meillo@46
|
1016 .], page 132]
|
meillo@21
|
1017 .QP
|
meillo@45
|
1018 [...] but [Stockton Gaines and Norm Shapiro] were not able
|
meillo@23
|
1019 to convince anyone that such a system would be fast enough to be usable.
|
meillo@21
|
1020 I proposed a very short project to prove the basic concepts,
|
meillo@21
|
1021 and my management agreed.
|
meillo@21
|
1022 Looking back, I realize that I had been very lucky with my first design.
|
meillo@21
|
1023 Without nearly enough design work,
|
meillo@21
|
1024 I built a working environment and some header files
|
meillo@21
|
1025 with key structures and wrote the first few \s-1MH\s0 commands:
|
meillo@21
|
1026 inc, show/next/prev, and comp.
|
meillo@21
|
1027 [...]
|
meillo@21
|
1028 With these three, I was able to convince people that the structure was viable.
|
meillo@21
|
1029 This took about three weeks.
|
meillo@0
|
1030
|
meillo@48
|
1031 .H 2 "Problems
|
meillo@0
|
1032 .LP
|
meillo@61
|
1033 \s-1MH\s0 is not without its problems.
|
meillo@61
|
1034 There are two main problems: one is technical, the other pertains to human behavior.
|
meillo@22
|
1035 .PP
|
meillo@61
|
1036 \s-1MH\s0 is old and email today is quite different than it was in the time
|
meillo@22
|
1037 when \s-1MH\s0 was designed.
|
meillo@61
|
1038 \s-1MH\s0 adapted to the changes fairly well, but it has its limitations.
|
meillo@22
|
1039 \s-1MIME\s0 support and support for different character encodings
|
meillo@22
|
1040 is available, but only on a moderate level.
|
meillo@45
|
1041 This comes from limited development resources.
|
meillo@61
|
1042 A larger and more active developer base could quickly remedy this.
|
meillo@45
|
1043 But \s-1MH\s0 is also limited by design, which is the larger problem.
|
meillo@54
|
1044 \s-1IMAP\s0, for example, conflicts with \s-1MH\s0's design to a large extent.
|
meillo@61
|
1045 These design conflicts are not easily solvable
|
meillo@61
|
1046 and may require a redesign.
|
meillo@61
|
1047 \s-1IMAP\s0 may be too incompatible with the classic mail model,
|
meillo@61
|
1048 which \s-1MH\s0 covers, so \s-1MH\s0 may never support it well.
|
meillo@61
|
1049 (Using \s-1IMAP\s0 and a filesystem abstraction layer to only map
|
meillo@61
|
1050 a remote directory into the local filesystem, is a different topic.
|
meillo@61
|
1051 \s-1IMAP\s0 support is seen as being able to access the special
|
meillo@61
|
1052 mail features of the protocol.)
|
meillo@22
|
1053 .PP
|
meillo@61
|
1054 The other kind of problem relates to human habits.
|
meillo@45
|
1055 In this world, where almost all \s-1MUA\s0s are monolithic,
|
meillo@61
|
1056 it is very difficult to convince people to use a toolchest-style \s-1MUA\s0
|
meillo@22
|
1057 like \s-1MH\s0.
|
meillo@61
|
1058 These habits are so strong, that even people who understand the concept
|
meillo@61
|
1059 and advantages of \s-1MH\s0 are reluctant to switch,
|
meillo@30
|
1060 simply because \s-1MH\s0 is different.
|
meillo@61
|
1061 Unfortunately, the frontends to \s-1MH\s0, which could provide familiar
|
meillo@61
|
1062 look and feel, are quite outdated and thus not very appealing in comparison
|
meillo@61
|
1063 to the modern interfaces of many monolithic \s-1MUA\s0s.
|
meillo@53
|
1064 One notable exception is \fImh-e\fP which provides an Emacs interface
|
meillo@53
|
1065 to \s-1MH\s0.
|
meillo@53
|
1066 \fIMh-e\fP looks much like \fImutt\fP or \fIpine\fP,
|
meillo@53
|
1067 but it has buttons, menus, and graphical display capabilities.
|
meillo@20
|
1068
|
meillo@53
|
1069 .H 2 "Summary
|
meillo@20
|
1070 .LP
|
meillo@45
|
1071 \s-1MH\s0 is an \s-1MUA\s0 that follows the Unix Philosophy in its design.
|
meillo@61
|
1072 It consists of a toolchest of small tools, each of which does one job well.
|
meillo@31
|
1073 The toolchest approach offers great flexibility to the user.
|
meillo@45
|
1074 It is possible to utilize the complete power of the Unix shell with \s-1MH\s0.
|
meillo@61
|
1075 This makes \s-1MH\s0 a very powerful mail system,
|
meillo@61
|
1076 and extending and customizing \s-1MH\s0 is easy and encouraged.
|
meillo@31
|
1077 .PP
|
meillo@31
|
1078 Apart from the user's perspective, \s-1MH\s0 is development-friendly.
|
meillo@31
|
1079 Its overall design follows clear rules.
|
meillo@61
|
1080 The single tools do only one job; thus they are easy to understand,
|
meillo@61
|
1081 write, and maintain.
|
meillo@31
|
1082 They are all independent and do not interfere with the others.
|
meillo@61
|
1083 Automated testing of their function is a straightforward task.
|
meillo@31
|
1084 .PP
|
meillo@61
|
1085 It is sad, that \s-1MH\s0's dissimilarity to other \s-1MUA\s0s is its
|
meillo@61
|
1086 largest problem, as this dissimilarity is also its largest advantage.
|
meillo@61
|
1087 Unfortunately, most people's habits are stronger
|
meillo@61
|
1088 than the attraction of the clear design and the power \s-1MH\s0 offers.
|
meillo@0
|
1089
|
meillo@8
|
1090
|
meillo@8
|
1091
|
meillo@48
|
1092 .H 1 "Case study: uzbl
|
meillo@32
|
1093 .LP
|
meillo@61
|
1094 The last chapter focused on the \s-1MUA\s0 \s-1MH\s0,
|
meillo@61
|
1095 which is an old and established piece of software.
|
meillo@45
|
1096 This chapter covers uzbl, a fresh new project.
|
meillo@45
|
1097 Uzbl is a web browser that adheres to the Unix Philosophy.
|
meillo@45
|
1098 Its name comes from the \fILolspeak\fP word for ``usable'';
|
meillo@61
|
1099 both are pronounced in the same way.
|
meillo@0
|
1100
|
meillo@48
|
1101 .H 2 "Historical background
|
meillo@0
|
1102 .LP
|
meillo@32
|
1103 Uzbl was started by Dieter Plaetinck in April 2009.
|
meillo@61
|
1104 The idea was born in a thread on the Arch Linux forums.
|
meillo@32
|
1105 .[
|
meillo@44
|
1106 arch linux forums
|
meillo@44
|
1107 browser
|
meillo@32
|
1108 .]
|
meillo@61
|
1109 After some discussion about the failures of well-known web browsers,
|
meillo@61
|
1110 Plaetinck (alias Dieter@be) came up with a rough proposal
|
meillo@61
|
1111 of how a better web browser could look.
|
meillo@61
|
1112 In response to another member who asked if Plaetinck would write this
|
meillo@61
|
1113 program because it sounded fantastic, Plaetinck replied:
|
meillo@32
|
1114 ``Maybe, if I find the time ;-)''.
|
meillo@32
|
1115 .PP
|
meillo@32
|
1116 Fortunately, he found the time.
|
meillo@32
|
1117 One day later, the first prototype was out.
|
meillo@61
|
1118 One week later, uzbl had its own website.
|
meillo@47
|
1119 .[
|
meillo@47
|
1120 uzbl website
|
meillo@47
|
1121 .]
|
meillo@61
|
1122 One month after the initial code was presented,
|
meillo@61
|
1123 a mailing list was set up to coordinate and discuss further development,
|
meillo@61
|
1124 and a wiki was added to store documentation and scripts that cropped up
|
meillo@61
|
1125 on the mailing list and elsewhere.
|
meillo@32
|
1126 .PP
|
meillo@61
|
1127 In the first year of uzbl's existence, it was heavily developed on various branches.
|
meillo@32
|
1128 Plaetinck's task became more and more to only merge the best code from the
|
meillo@32
|
1129 different branches into his main branch, and to apply patches.
|
meillo@47
|
1130 .[
|
meillo@47
|
1131 lwn uzbl
|
meillo@47
|
1132 .]
|
meillo@32
|
1133 About once a month, Plaetinck released a new version.
|
meillo@32
|
1134 In September 2009, he presented several forks of uzbl.
|
meillo@47
|
1135 .[ [
|
meillo@47
|
1136 uzbl website
|
meillo@47
|
1137 .], news archive]
|
meillo@61
|
1138 Uzbl actually opened the field for a whole family of web browsers with
|
meillo@61
|
1139 a similar design.
|
meillo@32
|
1140 .PP
|
meillo@61
|
1141 In July 2009, \fILinux Weekly News\fP published an interview with
|
meillo@61
|
1142 Plaetinck about uzbl.
|
meillo@47
|
1143 .[
|
meillo@47
|
1144 lwn uzbl
|
meillo@47
|
1145 .]
|
meillo@32
|
1146 In September 2009, the uzbl web browser was on \fISlashdot\fP.
|
meillo@47
|
1147 .[
|
meillo@47
|
1148 slashdot uzbl
|
meillo@47
|
1149 .]
|
meillo@0
|
1150
|
meillo@48
|
1151 .H 2 "Contrasts to other web browsers
|
meillo@0
|
1152 .LP
|
meillo@32
|
1153 Like most \s-1MUA\s0s are monolithic, but \s-1MH\s0 is a toolchest,
|
meillo@32
|
1154 most web browsers are monolithic, but uzbl is a frontend to a toolchest.
|
meillo@32
|
1155 .PP
|
meillo@32
|
1156 Today, uzbl is divided into uzbl-core and uzbl-browser.
|
meillo@61
|
1157 Uzbl-core is, as its name indicates, the core of uzbl.
|
meillo@61
|
1158 It handles commands and events to interface with other programs,
|
meillo@61
|
1159 and displays webpages by using \fIwebkit\fP as its rendering engine.
|
meillo@61
|
1160 Uzbl-browser combines uzbl-core with a selection of handler scripts,
|
meillo@61
|
1161 a status bar, an event manager, yanking, pasting, page searching,
|
meillo@61
|
1162 zooming, and much more functionality, to form a ``complete'' web browser.
|
meillo@61
|
1163 In the following text, the term ``uzbl'' usually refers to uzbl-browser,
|
meillo@32
|
1164 so uzbl-core is included.
|
meillo@32
|
1165 .PP
|
meillo@61
|
1166 Unlike most other web browsers, uzbl is mainly the mediator between
|
meillo@45
|
1167 various tools that cover single jobs.
|
meillo@61
|
1168 Uzbl listens for commands on a named pipe (fifo), a Unix socket,
|
meillo@35
|
1169 and on stdin, and it writes events to a Unix socket and to stdout.
|
meillo@35
|
1170 Loading a webpage in a running uzbl instance requires only:
|
meillo@32
|
1171 .DS
|
meillo@32
|
1172 echo 'uri http://example.org' >/path/to/uzbl-fifo
|
meillo@32
|
1173 .DE
|
meillo@61
|
1174 The rendering of the webpage is done by libwebkit,
|
meillo@61
|
1175 around which uzbl-core is built.
|
meillo@32
|
1176 .PP
|
meillo@45
|
1177 Downloads, browsing history, bookmarks, and the like are not provided
|
meillo@61
|
1178 by the core itself like they are in other web browsers.
|
meillo@61
|
1179 Uzbl-browser also only provides ``handler scripts'' which wrap
|
meillo@61
|
1180 external applications to provide the actual functionality.
|
meillo@32
|
1181 For instance, \fIwget\fP is used to download files and uzbl-browser
|
meillo@32
|
1182 includes a script that calls wget with appropriate options in
|
meillo@32
|
1183 a prepared environment.
|
meillo@32
|
1184 .PP
|
meillo@61
|
1185 Modern web browsers are proud to have addons, plugins, modules,
|
meillo@61
|
1186 and so forth.
|
meillo@32
|
1187 This is their effort to achieve similar goals.
|
meillo@61
|
1188 But instead of using existing external programs, modern web browsers
|
meillo@45
|
1189 include these functions.
|
meillo@0
|
1190
|
meillo@48
|
1191 .H 2 "Discussion of the design
|
meillo@0
|
1192 .LP
|
meillo@61
|
1193 This section discusses uzbl in regard to the Unix Philosophy,
|
meillo@32
|
1194 as identified by Gancarz.
|
meillo@32
|
1195
|
meillo@32
|
1196 .PP
|
meillo@35
|
1197 .B "Make each program do one thing well" .
|
meillo@35
|
1198 Uzbl tries to be a web browser and nothing else.
|
meillo@61
|
1199 The common definition of a web browser is highly influenced by
|
meillo@61
|
1200 existing implementations of web browsers.
|
meillo@61
|
1201 But a web browser should be a program to browse the web, and nothing more.
|
meillo@61
|
1202 This is the one thing it should do.
|
meillo@36
|
1203 .PP
|
meillo@61
|
1204 Web browsers should not, for instance, manage downloads;
|
meillo@61
|
1205 this is the job of download managers.
|
meillo@61
|
1206 A download manager is primary concerned with downloading files.
|
meillo@35
|
1207 Modern web browsers provide download management only as a secondary feature.
|
meillo@61
|
1208 How could they do this job better than programs that exist only for
|
meillo@35
|
1209 this very job?
|
meillo@61
|
1210 And why would anyone want less than the best download manager available?
|
meillo@32
|
1211 .PP
|
meillo@35
|
1212 A web browser's job is to let the user browse the web.
|
meillo@35
|
1213 This means, navigating through websites by following links.
|
meillo@36
|
1214 Rendering the \s-1HTML\s0 sources is a different job, too.
|
meillo@61
|
1215 In uzbl's case, this is covered by the webkit rendering engine.
|
meillo@61
|
1216 Handling audio and video content, PostScript, \s-1PDF\s0,
|
meillo@61
|
1217 and other such files are also not the job of a web browser.
|
meillo@61
|
1218 Such content should be handled by external programs
|
meillo@61
|
1219 that were written to handle such data.
|
meillo@35
|
1220 Uzbl strives to do it this way.
|
meillo@36
|
1221 .PP
|
meillo@61
|
1222 Remember Doug McIlroy's words:
|
meillo@35
|
1223 .I
|
meillo@35
|
1224 ``Write programs that do one thing and do it well.
|
meillo@35
|
1225 Write programs to work together.''
|
meillo@35
|
1226 .R
|
meillo@35
|
1227 .PP
|
meillo@35
|
1228 The lesser tenet
|
meillo@35
|
1229 .B "allow the user to tailor the environment
|
meillo@61
|
1230 applies here as well.
|
meillo@61
|
1231 Previously, the question, ``Why would anyone want anything less than the
|
meillo@61
|
1232 best program for the job?'' was put forward.
|
meillo@61
|
1233 But as personal preferences matter, it might be more important to ask:
|
meillo@61
|
1234 ``Why would anyone want something other than his preferred program for
|
meillo@61
|
1235 the job?''
|
meillo@36
|
1236 .PP
|
meillo@61
|
1237 Users typically want one program for a specific job.
|
meillo@61
|
1238 Hence, whenever one wishes to download something,
|
meillo@45
|
1239 the same download manager should be used.
|
meillo@61
|
1240 More advanced users might want to use one download manager in a certain
|
meillo@61
|
1241 situation and another in a different situation;
|
meillo@61
|
1242 they should be able to configure it this way.
|
meillo@61
|
1243 With uzbl, any download manager can be used.
|
meillo@61
|
1244 To switch to a different one, a single line in a small handler script
|
meillo@35
|
1245 needs to be changed.
|
meillo@61
|
1246 Alternatively, it would be possible to query which download manager to use by
|
meillo@61
|
1247 reading a global file or an environment variable in the handler script.
|
meillo@61
|
1248 Of course, uzbl can use a different handler script as well.
|
meillo@61
|
1249 This simply requires a one line change in uzbl's configuration file.
|
meillo@36
|
1250 .PP
|
meillo@61
|
1251 Uzbl neither has its own download manager nor depends on a specific one;
|
meillo@61
|
1252 hence, uzbl's browsing abilities will not be crippled by having
|
meillo@35
|
1253 a bad download manager.
|
meillo@61
|
1254 Uzbl's download capabilities will be as good as the best
|
meillo@36
|
1255 download manager available on the system.
|
meillo@38
|
1256 Of course, this applies to all of the other supplementary tools, too.
|
meillo@32
|
1257
|
meillo@32
|
1258 .PP
|
meillo@36
|
1259 .B "Use software leverage to your advantage" .
|
meillo@36
|
1260 Uzbl is designed to be extended by external tools.
|
meillo@36
|
1261 These external tools are usually wrapped by small handler shell scripts.
|
meillo@61
|
1262 Shell scripts form the basis for the glue which holds the various
|
meillo@61
|
1263 parts together.
|
meillo@36
|
1264 .PP
|
meillo@45
|
1265 The history mechanism of uzbl shall be presented as an example.
|
meillo@36
|
1266 Uzbl is configured to spawn a script to append an entry to the history
|
meillo@36
|
1267 whenever the event of a fully loaded page occurs.
|
meillo@45
|
1268 The script to append the entry to the history is not much more than:
|
meillo@36
|
1269 .DS
|
meillo@36
|
1270 #!/bin/sh
|
meillo@36
|
1271 file=/path/to/uzbl-history
|
meillo@36
|
1272 echo `date +'%Y-%m-%d %H:%M:%S'`" $6 $7" >> $file
|
meillo@36
|
1273 .DE
|
meillo@61
|
1274 \f(CW$6\fP and \f(CW$7\fP expand to the \s-1URL\s0 and the page title,
|
meillo@61
|
1275 respectively.
|
meillo@45
|
1276 .PP
|
meillo@45
|
1277 For loading an entry, a key is bound to spawn a load-from-history script.
|
meillo@36
|
1278 The script reverses the history to have newer entries first,
|
meillo@61
|
1279 displays \fIdmenu\fP to let the user select an item,
|
meillo@61
|
1280 and then writes the selected \s-1URL\s0 into uzbl's command input pipe.
|
meillo@45
|
1281 With error checking and corner case handling removed,
|
meillo@45
|
1282 the script looks like this:
|
meillo@36
|
1283 .DS
|
meillo@36
|
1284 #!/bin/sh
|
meillo@36
|
1285 file=/path/to/uzbl-history
|
meillo@36
|
1286 goto=`tac $file | dmenu | cut -d' ' -f 3`
|
meillo@36
|
1287 echo "uri $goto" > $4
|
meillo@36
|
1288 .DE
|
meillo@36
|
1289 \f(CW$4\fP expands to the path of the command input pipe of the current
|
meillo@36
|
1290 uzbl instance.
|
meillo@32
|
1291
|
meillo@32
|
1292 .PP
|
meillo@33
|
1293 .B "Avoid captive user interfaces" .
|
meillo@61
|
1294 One could say that uzbl, to a large extent, actually \fIis\fP
|
meillo@36
|
1295 a captive user interface.
|
meillo@61
|
1296 But the difference from other web browsers is that uzbl is only
|
meillo@45
|
1297 the captive user interface frontend (and the core of the backend).
|
meillo@38
|
1298 Many parts of the backend are independent of uzbl.
|
meillo@61
|
1299 For some external programs, handler scripts are distributed with uzbl;
|
meillo@61
|
1300 but arbitrary additional functionality can always be added if desired.
|
meillo@37
|
1301 .PP
|
meillo@37
|
1302 The frontend is captive \(en that is true.
|
meillo@37
|
1303 This is okay for the task of browsing the web, as this task is only relevant
|
meillo@61
|
1304 to humans.
|
meillo@61
|
1305 Automated programs would \fIcrawl\fP the web, that means,
|
meillo@61
|
1306 read the source directly, including all semantics.
|
meillo@61
|
1307 The graphical representation is just for humans to understand the semantics
|
meillo@37
|
1308 more intuitively.
|
meillo@32
|
1309
|
meillo@32
|
1310 .PP
|
meillo@33
|
1311 .B "Make every program a filter" .
|
meillo@37
|
1312 Graphical web browsers are almost dead ends in the chain of information flow.
|
meillo@37
|
1313 Thus it is difficult to see what graphical web browsers should filter.
|
meillo@61
|
1314 Graphical web browsers exist almost exclusively to be interactively used
|
meillo@61
|
1315 by humans.
|
meillo@61
|
1316 The only case in which one might want to automate the rendering function is
|
meillo@37
|
1317 to generate images of rendered webpages.
|
meillo@37
|
1318
|
meillo@37
|
1319 .PP
|
meillo@37
|
1320 .B "Small is beautiful"
|
meillo@61
|
1321 is not easy to apply to a web browser because modern web technology
|
meillo@61
|
1322 is very complex; hence, the rendering task is very complex.
|
meillo@61
|
1323 Unfortunately, modern web browsers ``have'' to consist of many thousand
|
meillo@61
|
1324 lines of code,
|
meillo@61
|
1325 Using the toolchest approach and wrappers can help to split the browser
|
meillo@61
|
1326 into several small parts, though.
|
meillo@37
|
1327 .PP
|
meillo@45
|
1328 As of March 2010, uzbl-core consists of about 3\,500 lines of C code.
|
meillo@37
|
1329 The distribution includes another 3\,500 lines of Shell and Python code,
|
meillo@61
|
1330 which are the handler scripts and plugins like one to provide a modal
|
meillo@61
|
1331 interface.
|
meillo@61
|
1332 Further more, uzbl makes use of external tools like
|
meillo@54
|
1333 \fIwget\fP and \fIsocat\fP.
|
meillo@37
|
1334 Up to this point, uzbl looks pretty neat and small.
|
meillo@61
|
1335 The ugly part of uzbl is the rendering engine, webkit.
|
meillo@37
|
1336 Webkit consists of roughly 400\,000 (!) lines of code.
|
meillo@61
|
1337 Unfortunately, small rendering engines are not feasible anymore
|
meillo@61
|
1338 due to the nature of the modern web.
|
meillo@35
|
1339
|
meillo@35
|
1340 .PP
|
meillo@35
|
1341 .B "Build a prototype as soon as possible" .
|
meillo@61
|
1342 Plaetinck made his code public right from the beginning.
|
meillo@61
|
1343 Discussion and development was, and still is, open to everyone interested,
|
meillo@61
|
1344 and development versions of uzbl can be obtained very easily from the
|
meillo@61
|
1345 code repository.
|
meillo@38
|
1346 Within the first year of uzbl's existence, a new version was released
|
meillo@35
|
1347 more often than once a month.
|
meillo@61
|
1348 Different forks and branches arose introducing new features which were
|
meillo@61
|
1349 then considered for merging into the main branch.
|
meillo@61
|
1350 The experiences with using prototypes influenced further development.
|
meillo@35
|
1351 Actually, all development was community driven.
|
meillo@38
|
1352 Plaetinck says, three months after uzbl's birth:
|
meillo@35
|
1353 ``Right now I hardly code anything myself for Uzbl.
|
meillo@35
|
1354 I just merge in other people's code, ponder a lot, and lead the discussions.''
|
meillo@35
|
1355 .[
|
meillo@44
|
1356 lwn
|
meillo@44
|
1357 uzbl
|
meillo@35
|
1358 .]
|
meillo@32
|
1359
|
meillo@0
|
1360
|
meillo@48
|
1361 .H 2 "Problems
|
meillo@0
|
1362 .LP
|
meillo@61
|
1363 Similar to \s-1MH\s0, uzbl suffers from being different.
|
meillo@38
|
1364 It is sad, but people use what they know.
|
meillo@61
|
1365 Fortunately, uzbl's user interface can be made to look and feel very similar
|
meillo@61
|
1366 to the one of the well known web browsers,
|
meillo@38
|
1367 hiding the internal differences.
|
meillo@38
|
1368 But uzbl has to provide this similar look and feel to be accepted
|
meillo@38
|
1369 as a ``normal'' browser by ``normal'' users.
|
meillo@37
|
1370 .PP
|
meillo@61
|
1371 The more important problem here is the modern web.
|
meillo@38
|
1372 The modern web is simply broken.
|
meillo@61
|
1373 It has state in a state-less protocol, misuses technologies,
|
meillo@61
|
1374 and is helplessly overloaded.
|
meillo@61
|
1375 This results in rendering engines that ``must'' consist
|
meillo@61
|
1376 of hundreds of thousands of lines of code.
|
meillo@61
|
1377 They also must combine and integrate many different technologies
|
meillo@61
|
1378 to make our modern web accessible.
|
meillo@61
|
1379 This results, however, in a failing attempt to provide good usability.
|
meillo@61
|
1380 Website-to-image converters are almost impossible to run without
|
meillo@38
|
1381 human interaction because of state in sessions, impossible
|
meillo@61
|
1382 deep-linking, and ``unautomatable'' technologies.
|
meillo@37
|
1383 .PP
|
meillo@61
|
1384 The web was misused in order to attempt to fulfill all kinds of wishes.
|
meillo@61
|
1385 Now web browsers, and ultimately users, suffer from it.
|
meillo@37
|
1386
|
meillo@8
|
1387
|
meillo@51
|
1388 .H 2 "Summary
|
meillo@32
|
1389 .LP
|
meillo@38
|
1390 ``Uzbl is a browser that adheres to the Unix Philosophy'',
|
meillo@61
|
1391 is how uzbl is seen by its authors.
|
meillo@38
|
1392 Indeed, uzbl follows the Unix Philosophy in many ways.
|
meillo@38
|
1393 It consists of independent parts that work together,
|
meillo@45
|
1394 while its core is mainly a mediator which glues the parts together.
|
meillo@38
|
1395 .PP
|
meillo@61
|
1396 Software leverage is put to excellent use.
|
meillo@61
|
1397 External tools are used, independent tasks are separated out
|
meillo@61
|
1398 to independent parts and glued together with small handler scripts.
|
meillo@38
|
1399 .PP
|
meillo@61
|
1400 Since uzbl roughly consists of a set of tools and a bit of glue,
|
meillo@61
|
1401 anyone can put the parts together and expand it in any desired way.
|
meillo@61
|
1402 Flexibility and customization are properties that make it valuable
|
meillo@61
|
1403 for advanced users, but may keep novice users from understanding
|
meillo@61
|
1404 and using it.
|
meillo@38
|
1405 .PP
|
meillo@61
|
1406 But uzbl's main problem is the modern web, which makes it very difficult
|
meillo@38
|
1407 to design a sane web browser.
|
meillo@38
|
1408 Despite this bad situation, uzbl does a fairly good job.
|
meillo@32
|
1409
|
meillo@8
|
1410
|
meillo@48
|
1411 .H 1 "Final thoughts
|
meillo@0
|
1412
|
meillo@0
|
1413 .LP
|
meillo@50
|
1414 This paper explained why good design is important.
|
meillo@61
|
1415 It introduced the Unix Philosophy as a set of guidelines that encourage
|
meillo@61
|
1416 good design in order to create good quality software.
|
meillo@61
|
1417 Then, real world software that was designed with the Unix Philosophy
|
meillo@61
|
1418 in mind was discussed.
|
meillo@50
|
1419 .PP
|
meillo@61
|
1420 Throughout this paper, the aim was do explain \fIwhy\fP something
|
meillo@50
|
1421 should be done the Unix way.
|
meillo@61
|
1422 Reasons were given to substantiate the claim that the Unix Philosophy
|
meillo@61
|
1423 is a preferable way of designing software.
|
meillo@50
|
1424 .PP
|
meillo@50
|
1425 The Unix Philosophy is close to the software developer's point of view.
|
meillo@61
|
1426 Its main goal is taming the beast known as ``software complexity''.
|
meillo@61
|
1427 Hence it strives first and foremost for simplicity of software.
|
meillo@61
|
1428 It might appear that usability for humans is a minor goal,
|
meillo@61
|
1429 but actually, the Unix Philosophy sees usability as a result of sound design.
|
meillo@61
|
1430 Sound design does not need to be ultimately intuitive,
|
meillo@50
|
1431 but it will provide a consistent way to access the enormous power
|
meillo@50
|
1432 of software leverage.
|
meillo@50
|
1433 .PP
|
meillo@61
|
1434 Being able to solve some specific concrete problem becomes less and less
|
meillo@61
|
1435 important as there is software available for nearly every possible task
|
meillo@61
|
1436 today.
|
meillo@50
|
1437 But the quality of software matters.
|
meillo@50
|
1438 It is important that we have \fIgood\fP software.
|
meillo@50
|
1439 .sp
|
meillo@0
|
1440 .LP
|
meillo@50
|
1441 .B "But why the Unix Philosophy?
|
meillo@50
|
1442 .PP
|
meillo@50
|
1443 The largest problem of software development is the complexity involved.
|
meillo@50
|
1444 It is the only part of the job that computers cannot take over.
|
meillo@61
|
1445 The Unix Philosophy fights complexity, as it is the main enemy.
|
meillo@50
|
1446 .PP
|
meillo@50
|
1447 On the other hand,
|
meillo@61
|
1448 the most unique advantage of software is its ability to leverage.
|
meillo@50
|
1449 Current software still fails to make the best possible use of this ability.
|
meillo@61
|
1450 The Unix Philosophy concentrates on exploiting this great opportunity.
|
meillo@0
|
1451
|
meillo@47
|
1452
|
meillo@47
|
1453 .bp
|
meillo@47
|
1454 .TL
|
meillo@47
|
1455 References
|
meillo@47
|
1456 .LP
|
meillo@47
|
1457 .XS
|
meillo@47
|
1458 .sp .5v
|
meillo@47
|
1459 .B
|
meillo@47
|
1460 References
|
meillo@47
|
1461 .XE
|
meillo@47
|
1462 .ev r
|
meillo@42
|
1463 .nr PS -1
|
meillo@42
|
1464 .nr VS -1
|
meillo@0
|
1465 .[
|
meillo@0
|
1466 $LIST$
|
meillo@0
|
1467 .]
|
meillo@47
|
1468 .nr PS +1
|
meillo@47
|
1469 .nr VS +1
|
meillo@47
|
1470 .ev
|
meillo@47
|
1471
|
meillo@42
|
1472 .bp
|
meillo@47
|
1473 .TL
|
meillo@47
|
1474 Table of Contents
|
meillo@47
|
1475 .LP
|
meillo@47
|
1476 .PX no
|