File and Directory Manipulation =============================== You already know how to list the names of files in a directory, ``ls -l``. To display the contents of a file itself you issue the command ``cat``. Although this command attracts a decent amount of justifiable abuse for its obscurity, it has the clear advantage of being easy to type. Try it by using it on a file in my home area :: % cat ~coan/cats.txt Note that you did not have to specify the full pathname of the file. Why the "catenate" command ``cat`` is named such is maybe illustrate by issuing the following command on 2 files in my home area. (Note: you do **not** have to be in my home area to execute the commands!): :: % cat ~coan/j1.txt ~coan/j2.txt Yuk-yuk. You have catenated two files and written them to a special file, the monitor, whose formal linux name is ``stdout``. The result works for an arbitrary number of files. Does the *order* of the files in the ``cat`` command matter? Try it! :: % cat ~coan/j2.txt ~coan/j1.txt Do you get the identical result as before? One disadvantage of ``cat`` is that it spits out the entire file at you. For long files that maybe fill many screens this is annoying. So, there is a command to use that returns more manageable chunks of data, the ``more`` command. Try it on a long file I made from the file listing of my home directory on the linux box in my office. :: % more ~coan/home_list.txt The semicolon at the bottom of the output is the clue that there is more output to come. You now have several options. If you want to see another page's worth of stuff, hit the **space** bar. If you just want to see the next line of output, hit the **enter** key. If you are utterly bored and just want to **quit** seeing anything, hit the **q** key. Puns are charming to linux penguins so the ``less`` command was invented. (I am not making this up.) See if you can figure out how ``less`` works. :: % less ~coan/home_list.txt Sometimes, such as when you are examining log files, it is useful to see only the top or bottom of a file. This is really useful when the file is very long. Linux has a solution to this as well. To see the top of the file, you use the ``head`` command. By default, it shows only the first 10 lines in a file. If you want to see more, issue it with an integer switch showing the number of lines you want to see. Here we go: :: % head ~coan/home_list.txt % head -15 ~coan/home_list.txt Did you count the lines of output? Now, if an animal has a head, it probably has a tail. (We could use an earthier term for the latter but this tutorial is suitable for the entire family.) Issue the ``tail`` command to see the last lines of a file. The defaults and switches are identical to those for ``more``. :: % tail ~coan/home_list.txt % tail -3 ~coan/home_list.txt Again, did you verify the line count? Often we want to copy (and delete) existing files. Copying an exiting file is done with the ``cp`` command. Copy my home area listing to your home area by issuing the command: :: % cp ~coan/home_list.txt ~/tec_list.txt Here, I also renamed the file "tec_list.txt", although I did not have to do so. If the file you are copying is long, and you are either lazy or which to avoid typos, there is a *very useful* typing shortcut that uses a single dot notation. Copy my home listing to your home directory but this time do not change the name: :: % cp ~coan/home_list.txt ~/. Do you see this file in your home directory? Suppose we wish to rename a file but do **not** want to copy it. Do you issue the ``rename`` command? Negative. Way too many letters to type. Instead, issue the *move* command ``mv``. Let's rename the file home_list.txt in your home area to listing.txt: :: % mv home_list.txt listing.txt Do you see listing.txt? Do you see home_list.txt? try renaming the file of the same name in **my** home area? What happens? :: % mv ~coan/home_list.txt listing.txt The difficulty is related to the permissions associated with this file, a topic we merely mentioned above. In general, you can only copy or delete files *you* created. We'll talk more about permissions later. There is no need to keep so many copies around of my home area listing. Let's delete some (or all of them) of them. The linux command for delete ("remove") is terse but a bit obscure, the ``rm`` command. Try it on a file in your home area: :: % rm home_list.txt Were you successful? What happens when you :: % ls -l home_list.txt In this chapter we have just discussed regular files. Creating a *directory* is done with the "make directory" command ``mkdir``. In your home area make a directory called "workshop" and one called "junk" :: % mkdir workshop % mkdir junk Do you see it? Copy some files into this directory. For later exercises, copy the listing of my home directory to there. :: % cp ~coan/home_list.txt ~/workshop/home_list.txt By-the-by, you may object this last command is a bit verbose if you are already in the destination directory "workshop." You are correct! **IF** you are already in workshop, you can just do this: :: % cp ~coan/home_list.txt ./. The first dot says copy the file in question into your *current* directory and the second dot says keep the same name. We need to separate the dots (since a double dot has its own meaning) so the slash is used. You now have a user created directory containing at least one file. Just as we did with vanilla files containing data, we want to know the attributes of our directory. First, go to your home directory, and then issue an ``ls -l`` :: % cd ~ % ls -l workshop What do you see? I thought we wanted to see attributes of the *directory* and not (necessarily) its contents. To see **just** the attributes of the directory file itself you need to use the ``-d`` switch with ``ls``: :: % ls -ld workshop Feel better now? The `-d`` switch with ``ls`` is particularly useful if you want to see the attributes of directories. While we are at it, issue a boring ``ls`` on your home area: :: % ls What do you see? Filenames with a forward slash "/" at their end indicate that a file is a directory. What can be created can be destroyed. To delete directories you issue the "remove directory" command ``rmdir``. Let's delete the directory "junk". To do so, you must be in a directory that contains "junk". :: % cd ~ % rmdir junk Verify that "junk"is gone. Was your deletion successful? Now that we know how to create directories, the files that contain other files, let's create some regular files, files that contain data. Probably the easiest way to create such a file is to use the command ``touch``. This is a very fast way to create an empty file for either testing or later editing with a text editor. You use it with the name of the file you wish to create. In your home area create the file junko.txt: :: % touch junko.txt That's it. Verify the file exists and check its size. Note its creation time. If you "touch" it again, the modification time reported by ``ls -l`` will change. Try it: :: % touch junko.txt You will probably need to wait 1 minute before "touching" the file again so that its modification time increments by at least 1 minute. How do you put content into a regular file? We'll use the editor "gedit," installed on smuhpc. There are other editors. (I use *emacs*, a powerful editor that is also on smuhpc but one that takes a bit of time to learn.) Open junko.txt with gedit: :: % gedit junko.txt You should see a window like this pop up: .. image:: gedit.png :height: 600 :width: 1200 :scale: 50 Go ahead and type away in the white rectangle. I'll leave it to you to Mouse around and figure out how to save what you typed. gedit is a common editor on linux systems. Again, there are numerous others. If you look back at the window in which you launched gedit you will see no cursor. This means you cannot use the window for anything else until gedit is closed. This is sometimes annoying. To avoid this, you want to run gedit "in the background." gedit runs but you still can use the window to launch other commands. Try it. Dismiss gedit and relaunch it in the background in this fashion: :: % gedit junko.txt & The trailing ampersand & is the key. This trick of the trailing ampersand works for any command and my advice is to use it often so you do not clutter your screen with windows. We'll talk more about background processes later. Suppose you typed sensitive information into junko.txt and you do not want others to be able to see it or copy it, like you did for files in my home area. Recall from before that when you issued the ``ls -l`` command it gave you information about the so-called permissions associated with a file. I issue that command for junko.txt: :: % ls -l junko.txt You will see something similar to what I see when I do the same. :: % -rw-r--r-- 1 coan physics 19 May 31 22:04 junko.txt The important information is at the far left. You see a total of 9 slots, some filled an an "r" or a "w" or a dash. The 9 slots are grouped in sets of 3, representing all possible people who might access the file: "user" (owner), "group" or "other" (everybody else), in that order (just think "ugo"). The presence of an "r" in a slot means the corresponding type of person can read that file. (The jargon is that the person type has read access to the file.) From above you see 3 r's so the file's owner, the group the owner is a member of, and all other types of people can read the file. There is only a single w and that is in the user's set of 3 slots, so only the file owner can write to that file. If you try to gedit *my* junko.txt you will fail. Try it and see! Likewise, I cannot edit your junko.txt. (At the risk of stating the obvious, the root administrator can see all files regardless of how you set permissions so do not store, say, your love letters on your SMU linux machine.) Now, if you want to make your file secret, you need to remove read permission for "group" and "other". You do this by using the "change mode" command ``chmod``. You specify what people are to be effected and what permissions are to be changed. To make junko.txt readable and writeable by only you, do this: :: % chmod u=rw,go= junko.txt Note the syntax. The user (you) got an "r" and a "w". Group (g) and all others (o) got nothing because there is nothing past the second equals sign. See if you can guess how to add back the read permissions for group and other. Were you successful? The third slot associated with each member of ugo describes whether or not a file is executable. If a file is executable you only need to type its name and press enter for the commands that the file contains to be executed. However, this type of file will only execute if it has an "x" in the appropriate slot. Scripts are files that need the "x". An alternative way to set file permissions is to use the numerical scheme. Here you use ``chmod`` but give it an integer and the name of the file to act on. The value of the integer encodes the read/write/execute permission in a straightforward way. The correspondence is :: 400 read by user (owner) 040 read by group 004 read by other 200 write by user (owner) 020 write by group 002 write by other 100 execute by user (owner) 010 execute by group 001 execute by other Permissions for a file for the various types of people are defined by the sum of the individual permissions. For example, to set read and write for the user but only read for group and other you issue: :: % chmod 644 junko.txt since 400 + 200 + 40 + 4 = 644. This is a common file permission setting. Memorizing the above list is not necessary. That is what the ``man`` command is for: :: % man chmod Google also helps of course. Now that you can create files, it is worth emphasizing that linux is designed to minimize typing and has several features that assist you, besides the general terseness of the commands. There are 2 types of wildcard characters associated with file names: * and ?. Their use is best illustrated by example. If you wish to list all files that contain the letter "p" anywhere in their name you can simply issue: :: % ls *p* The * character stand for any number of keyboard characters (including zero) and the string of characters before and after the "p" can be different. Using the ``touch`` create some files that have different names but that all contain a "p" and then use ``ls`` to verify the behavior of the * wildcard: :: % ls *p* % ls *p % ls p* The ? wildcard stands for a *single* keyboard character. Not 2, 3 or 77. Again, using ``touch``and ``ls`` verify this behavior. You can combine * and ? in the same ``ls`` command, in any order. Linux also allows "filename tab completion" for its commands typed at the keyboard that operate on files. This means you only have to type the first unambiguous characters of a filename, hit tab, and linux will complete the name! If the characters you enter are ambiguous, linux helps you by displaying in the window what your choices are. In that case you just type more letters. **Try it!** Were you successful? Linux also keep a record of the commands you issued. To automatically recall previous commands, use the "up" and "down" arrows on the keyboard to select the comand you want. Once it is displayed on the command line, hit "enter." Additionally, you can use the the history command ``history``. Linux assigns an integer to each command (up to a large limit). To see this, just type :: % history Wow. To issue one of the commands you now see in the list, say command 24, just issue :: % !24 Convenient, no? Th exclamation point technique also works with the starting letters of a previous command. Just include enough characters to unambiguously identify a previous command. To invoke the ``history`` command again we can issue: :: % !hi If you do have two or more previous commands that begin with the characters "hi" , then the most recently issued command starting with "hi" will be reissued. Verify this by issuing ``less`` and then ``ls`` on some file and then see what happens when you issue: :: % !l % !le Smokin'! Who knew penguins were so efficient? Summary ------- ========================= ============================== Command Meaning ========================= ============================== cat madness.txt prints madness.txt to shell window cat dr.txt no.txt prints dr.txt and then no.txt to shell window more money.txt displays 1 screenful at a time of money.txt less money.txt displays 1 screenful at a time of money.txt head case.txt displays first 10 lines of case.txt head -7 case.txt displays first 7 lines of case.txt tail case.txt displays last 10 lines of case.txt tail -6 case.txt displays last 6 lines of case.txt cp apple.txt fruit.txt duplicate apple.txt and call it fruit.txt mv seed.txt flower.txt rename seed.txt and call it flower.txt rm war.txt delete war.txt mkdir justice create the directory justice in your working directory rmdir mess delete the directory mess touch instance.txt create empty file instance.txt without an editor gedit beauty.txt & edit file beauty.txt and retain use of command line chmod u=rw,g=r,o= abc.txt grant read/write access to user, read to group, nothing to others history lists previously issued commands !33 reissues command 33 !his reissue most recent last command starting with the letters "his" ========================= ==============================