261b9a1fc6ab43b2a42adf1a883d335fd6791f25
[swc-modular-shell.git] / 01-filedir.md
1 <div class="objectives" markdown="1">
2
3 #### Objectives
4 *   Explain the similarities and differences between a file and a directory.
5 *   Translate an absolute path into a relative path and vice versa.
6 *   Construct absolute and relative paths that identify specific files and directories.
7 *   Explain the steps in the shell's read-run-print cycle.
8 *   Identify the actual command, flags, and filenames in a command-line call.
9 *   Demonstrate the use of tab completion, and explain its advantages.
10
11 </div>
12
13 The part of the operating system responsible for managing files and directories
14 is called the [file system](../../gloss.html#filesystem).
15 It organizes our data into files,
16 which hold information,
17 and directories (also called "folders"),
18 which hold files or other directories.
19
20 Several commands are frequently used to create, inspect, rename, and delete files and directories.
21 To start exploring them,
22 let's open a shell window:
23
24 <div class="in" markdown="1">
25 ~~~
26 $
27 ~~~
28 </div>
29
30 The dollar sign is a [prompt](../../gloss.html#prompt),
31 which shows us that the shell is waiting for input;
32 your shell may show something more elaborate.
33
34 Type the command `whoami`,
35 then press the Enter key (sometimes marked Return) to send the command to the shell.
36 The command's output is the ID of the current user,
37 i.e.,
38 it shows us who the shell thinks we are:
39
40 <div class="in" markdown="1">
41 ~~~
42 $ whoami
43 ~~~
44 </div>
45 <div class="out" markdown="1">
46 ~~~
47 vlad
48 ~~~
49 </div>
50
51 More specifically, when we type `whoami` the shell:
52
53 1.  finds a program called `whoami`,
54 2.  runs that program,
55 3.  displays that program's output, then
56 4.  displays a new prompt to tell us that it's ready for more commands.
57
58 Next,
59 let's find out where we are by running a command called `pwd`
60 (which stands for "print working directory").
61 At any moment,
62 our [current working directory](../../gloss.html#current-working-directory)
63 is our current default directory,
64 i.e.,
65 the directory that the computer assumes we want to run commands in
66 unless we explicitly specify something else.
67 Here,
68 the computer's response is `/users/vlad`,
69 which is Vlad's [home directory](../../gloss.html#home-directory):
70
71 <div class="in" markdown="1">
72 ~~~
73 $ pwd
74 ~~~
75 </div>
76 <div class="out" markdown="1">
77 ~~~
78 /users/vlad
79 ~~~
80 </div>
81
82 > #### Alphabet Soup
83
84 > If the command to find out who we are is `whoami`, the command to find
85 > out where we are ought to be called `whereami`, so why is it `pwd`
86 > instead? The usual answer is that in the early 1970s, when Unix was
87 > first being developed, every keystroke counted: the devices of the day
88 > were slow, and backspacing on a teletype was so painful that cutting the
89 > number of keystrokes in order to cut the number of typing mistakes was
90 > actually a win for usability. The reality is that commands were added to
91 > Unix one by one, without any master plan, by people who were immersed in
92 > its jargon. The result is as inconsistent as the roolz uv Inglish
93 > speling, but we're stuck with it now.
94
95 To understand what a "home directory" is,
96 let's have a look at how the file system as a whole is organized.
97 At the top is the [root directory](../../gloss.html#root-directory)
98 that holds everything else.
99 We refer to it using a slash character `/` on its own;
100 this is the leading slash in `/users/vlad`.
101
102 Inside that directory are several other directories:
103 `bin` (which is where some built-in programs are stored),
104 `data` (for miscellaneous data files),
105 `users` (where users' personal directories are located),
106 `tmp` (for temporary files that don't need to be stored long-term),
107 and so on:
108
109 <img src="img/filesystem.svg" alt="The Filesystem" />
110
111 We know that our current working directory `/users/vlad` is stored inside `/users`
112 because `/users` is the first part of its name.
113 Similarly,
114 we know that `/users` is stored inside the root directory `/`
115 because its name begins with `/`.
116
117 Underneath `/users`,
118 we find one directory for each user with an account on this machine.
119 The Mummy's files are stored in `/users/imhotep`,
120 Wolfman's in `/users/larry`,
121 and ours in `/users/vlad`,
122 which is why `vlad` is the last part of the directory's name.
123
124 <img src="img/home-directories.svg" alt="Home Directories" />
125
126 > Notice that there are two meanings for the `/` character.
127 > When it appears at the front of a file or directory name,
128 > it refers to the root directory. When it appears *inside* a name,
129 > it's just a separator.
130
131 Let's see what's in Vlad's home directory by running `ls`,
132 which stands for "listing":
133
134 <div class="in" markdown="1">
135 ~~~
136 $ ls
137 ~~~
138 </div>
139 <div class="out" markdown="1">
140 ~~~
141 bin          data      mail       music
142 notes.txt    papers    pizza.cfg  solar
143 solar.pdf    swc
144 ~~~
145 </div>
146
147 <img src="img/vlad-homedir.svg" alt="Vlad's Home Directory" />
148
149 `ls` prints the names of the files and directories in the current directory in alphabetical order,
150 arranged neatly into columns.
151 We can make its output more comprehensible by using the [flag](../../gloss.html#command-line-flag) `-F`,
152 which tells `ls` to add a trailing `/` to the names of directories:
153
154 <div class="in" markdown="1">
155 ~~~
156 $ ls -F
157 ~~~
158 </div>
159 <div class="out" markdown="1">
160 ~~~
161 bin/         data/     mail/      music/
162 notes.txt    papers/   pizza.cfg  solar/
163 solar.pdf    swc/
164 ~~~
165 </div>
166
167 Here,
168 we can see that `/users/vlad` contains seven [sub-directories](../../gloss.html#sub-directory).
169 The names that don't have trailing slashes,
170 like `notes.txt`, `pizza.cfg`, and `solar.pdf`,
171 are plain old files.
172 And note that there is a space between `ls` and `-F`:
173 without it,
174 the shell thinks we're trying to run a command called `ls-F`,
175 which doesn't exist.
176
177 > #### What's In A Name?
178
179 > You may have noticed that all of Vlad's files' names are "something dot
180 > something". This is just a convention: we can call a file `mythesis` or
181 > almost anything else we want. However, most people use two-part names
182 > most of the time to help them (and their programs) tell different kinds
183 > of files apart. The second part of such a name is called the
184 > [filename extension](../../gloss.html#filename-extension), and indicates
185 > what type of data the file holds: `.txt` signals a plain text file, `.pdf`
186 > indicates a PDF document, `.cfg` is a configuration file full of parameters
187 > for some program or other, and so on.
188 >
189 > This is just a convention, albeit an important one. Files contain
190 > bytes: it's up to us and our programs to interpret those bytes
191 > according to the rules for PDF documents, images, and so on.
192 >
193 > Naming a PNG image of a whale as `whale.mp3` doesn't somehow
194 > magically turn it into a recording of whalesong, though it *might*
195 > cause the operating system to try to open it with a music player
196 > when someone double-clicks it.
197
198 Now let's take a look at what's in Vlad's `data` directory by running `ls -F data`,
199 i.e.,
200 the command `ls` with the parameters `-F` and `data`.
201 The second parameter&mdash;the one *without* a leading dash&mdash;tells `ls` that
202 we want a listing of something other than our current working directory:
203
204 <div class="in" markdown="1">
205 ~~~
206 $ ls -F data
207 ~~~
208 </div>
209 <div class="out" markdown="1">
210 ~~~
211 amino-acids.txt   elements/     morse.txt
212 pdb/              planets.txt   sunspot.txt
213 ~~~
214 </div>
215
216 The output shows us that there are four text files and two sub-sub-directories.
217 Organizing things hierarchically in this way helps us keep track of our work:
218 it's possible to put hundreds of files in our home directory,
219 just as it's possible to pile hundreds of printed papers on our desk,
220 but it's a self-defeating strategy.
221
222 Notice, by the way that we spelled the directory name `data`.
223 It doesn't have a trailing slash:
224 that's added to directory names by `ls` when we use the `-F` flag to help us tell things apart.
225 And it doesn't begin with a slash because it's a [relative path](../../gloss.html#relative-path),
226 i.e., it tells `ls` how to find something from where we are,
227 rather than from the root of the file system.
228
229 If we run `ls -F /data` (*with* a leading slash) we get a different answer,
230 because `/data` is an [absolute path](../../gloss.html#absolute-path):
231
232 <div class="in" markdown="1">
233 ~~~
234 $ ls -F /data
235 ~~~
236 </div>
237 <div class="out" markdown="1">
238 ~~~
239 access.log    backup/    hardware.cfg
240 network.cfg
241 ~~~
242 </div>
243
244 The leading `/` tells the computer to follow the path from the root of the filesystem,
245 so it always refers to exactly one directory,
246 no matter where we are when we run the command.
247
248 What if we want to change our current working directory?
249 Before we do this,
250 `pwd` shows us that we're in `/users/vlad`,
251 and `ls` without any parameters shows us that directory's contents:
252
253 <div class="in" markdown="1">
254 ~~~
255 $ pwd
256 ~~~
257 </div>
258 <div class="out" markdown="1">
259 ~~~
260 /users/vlad
261 ~~~
262 </div>
263 <div class="in" markdown="1">
264 ~~~
265 $ ls
266 ~~~
267 </div>
268 <div class="out" markdown="1">
269 ~~~
270 bin/         data/     mail/      music/
271 notes.txt    papers/   pizza.cfg  solar/
272 solar.pdf    swc/
273 ~~~
274 </div>
275
276 We can use `cd` followed by a directory name to change our working directory.
277 `cd` stands for "change directory",
278 which is a bit misleading:
279 the command doesn't change the directory,
280 it changes the shell's idea of what directory we are in.
281
282 <div class="in" markdown="1">
283 ~~~
284 $ cd data
285 ~~~
286 </div>
287
288 `cd` doesn't print anything,
289 but if we run `pwd` after it, we can see that we are now in `/users/vlad/data`.
290 If we run `ls` without parameters now,
291 it lists the contents of `/users/vlad/data`,
292 because that's where we now are:
293
294 <div class="in" markdown="1">
295 ~~~
296 $ pwd
297 ~~~
298 </div>
299 <div class="out" markdown="1">
300 ~~~
301 /users/vlad/data
302 ~~~
303 </div>
304 <div class="in" markdown="1">
305 ~~~
306 $ ls
307 ~~~
308 </div>
309 <div class="out" markdown="1">
310 ~~~
311 amino-acids.txt   elements/     morse.txt
312 pdb/              planets.txt   sunspot.txt
313 ~~~
314 </div>
315
316 We now know how to go down the directory tree:
317 how do we go up?
318 We could use an absolute path:
319
320 <div class="in" markdown="1">
321 ~~~
322 $ cd /users/vlad
323 ~~~
324 </div>
325
326 but it's almost always simpler to use `cd ..` to go up one level:
327
328 <div class="in" markdown="1">
329 ~~~
330 $ pwd
331 ~~~
332 </div>
333 <div class="out" markdown="1">
334 ~~~
335 /users/vlad/data
336 ~~~
337 </div>
338 <div class="in" markdown="1">
339 ~~~
340 $ cd ..
341 ~~~
342 </div>
343
344 `..` is a special directory name meaning
345 "the directory containing this one",
346 or more succinctly,
347 the [parent](../../gloss.html#parent-directory) of the current directory.
348 Sure enough,
349 if we run `pwd` after running `cd ..`, we're back in `/users/vlad`:
350
351 <div class="in" markdown="1">
352 ~~~
353 $ pwd
354 ~~~
355 </div>
356 <div class="out" markdown="1">
357 ~~~
358 /users/vlad
359 ~~~
360 </div>
361
362 The special directory `..` doesn't usually show up when we run `ls`.
363 If we want to display it, we can give `ls` the `-a` flag:
364
365 <div class="in" markdown="1">
366 ~~~
367 $ ls -F -a
368 ~~~
369 </div>
370 <div class="out" markdown="1">
371 ~~~
372 ./           ../       bin/       data/
373 mail/        music/    notes.txt  papers/
374 pizza.cfg    solar/    solar.pdf    swc/
375 ~~~
376 </div>
377
378 `-a` stands for "show all";
379 it forces `ls` to show us file and directory names that begin with `.`,
380 such as `..` (which, if we're in `/users/vlad`, refers to the `/users` directory).
381 As you can see,
382 it also displays another special directory that's just called `.`,
383 which means "the current working directory".
384 It may seem redundant to have a name for it,
385 but we'll see some uses for it soon.
386
387 > #### Orthogonality
388
389 > The special names `.` and `..` don't belong to `ls`;
390 > they are interpreted the same way by every program.
391 > For example,
392 > if we are in `/users/vlad/data`,
393 > the command `ls ..` will give us a listing of `/users/vlad`.
394 > When the meanings of the parts are the same no matter how they're combined,
395 > programmers say they are [orthogonal](../../gloss.html#orthogonal):
396 > Orthogonal systems tend to be easier for people to learn
397 > because there are fewer special cases and exceptions to keep track of.
398
399 #### Nelle's Pipeline: Organizing Files
400
401 Knowing just this much about files and directories,
402 Nelle is ready to organize the files that the protein assay machine will create.
403 First,
404 she creates a directory called `north-pacific-gyre`
405 (to remind herself where the data came from).
406 Inside that,
407 she creates a directory called `2012-07-03`,
408 which is the date she started processing the samples.
409 She used to use names like `conference-paper` and `revised-results`,
410 but she found them hard to understand after a couple of years.
411 (The final straw was when she found herself creating
412 a directory called `revised-revised-results-3`.)
413
414 > Nelle names her directories "year-month-day",
415 > with leading zeroes for months and days,
416 > because the shell displays file and directory names in alphabetical order.
417 > If she used month names,
418 > December would come before July;
419 > if she didn't use leading zeroes,
420 > November ('11') would come before July ('7').
421
422 Each of her physical samples is labelled according to her lab's convention
423 with a unique ten-character ID,
424 such as "NENE01729A".
425 This is what she used in her collection log
426 to record the location, time, depth, and other characteristics of the sample,
427 so she decides to use it as part of each data file's name.
428 Since the assay machine's output is plain text,
429 she will call her files `NENE01729A.txt`, `NENE01812A.txt`, and so on.
430 All 1520 files will go into the same directory.
431
432 If she is in her home directory,
433 Nelle can see what files she has using the command:
434
435 <div class="in" markdown="1">
436 ~~~
437 $ ls north-pacific-gyre/2012-07-03/
438 ~~~
439 </div>
440
441 This is a lot to type,
442 but she can let the shell do most of the work.
443 If she types:
444
445 <div class="in" markdown="1">
446 ~~~
447 $ ls no
448 ~~~
449 </div>
450
451 and then presses tab,
452 the shell automatically completes the directory name for her:
453
454 <div class="in" markdown="1">
455 ~~~
456 $ ls north-pacific-gyre/
457 ~~~
458 </div>
459
460 If she presses tab again,
461 Bash will add `2012-07-03/` to the command,
462 since it's the only possible completion.
463 Pressing tab again does nothing,
464 since there are 1520 possibilities;
465 pressing tab twice brings up a list of all the files,
466 and so on.
467 This is called [tab completion](../../gloss.html#tab-completion),
468 and we will see it in many other tools as we go on.
469
470 <div class="keypoints" markdown="1">
471
472 #### Key Points
473 *   The file system is responsible for managing information on the disk.
474 *   Information is stored in files, which are stored in directories (folders).
475 *   Directories can also store other directories, which forms a directory tree.
476 *   `/` on its own is the root directory of the whole filesystem.
477 *   A relative path specifies a location starting from the current location.
478 *   An absolute path specifies a location from the root of the filesystem.
479 *   Directory names in a path are separated with '/' on Unix, but '\\' on Windows.
480 *   '..' means "the directory above the current one";
481     '.' on its own means "the current directory".
482 *   Most files' names are `something.extension`.
483     The extension isn't required,
484     and doesn't guarantee anything,
485     but is normally used to indicate the type of data in the file.
486 *   Most commands take options (flags) which begin with a '-'.
487
488 </div>
489
490 <div class="challenges" markdown="1">
491
492 #### Challenges
493
494 <img src="img/filesystem-challenge.svg" alt="Filesystem for Challenge Questions" />
495
496 1.  If `pwd` displays `/users/thing`, what will `ls ../backup` display?
497     1.  `../backup: No such file or directory`
498     2.  `2012-12-01 2013-01-08 2013-01-27`
499     3.  `2012-12-01/ 2013-01-08/ 2013-01-27/`
500     4.  `original pnas_final pnas_sub`
501
502 2.  If `pwd` displays `/users/backup`,
503     and `-r` tells `ls` to display things in reverse order,
504     what command will display:
505
506     ~~~
507     pnas-sub/ pnas-final/ original/
508     ~~~
509
510     1.  `ls pwd`
511     2.  `ls -r -F`
512     3.  `ls -r -F /users/backup`
513     4.  Either \#2 or \#3 above, but not \#1.
514
515 3.  What does the command `cd` without a directory name do?
516     1.  It has no effect.
517     2.  It changes the working directory to `/`.
518     3.  It changes the working directory to the user's home directory.
519     4.  It produces an error message.
520
521 </div>