Sunday, January 30, 2011

Unix spoken here (2)

Let's continue with an introduction to Unix commands. First post here. And here are two more good links (one, two).

Let's start by putting some data into a file. We can use the command echo and the `>` redirection operator. Take a look at what's there with cat:


> cd
> cd Desktop
> echo "abc" > x.txt
> cat x.txt
abc


Suppose we wish to move this file to a new sub-directory. First we construct the new directory and then we move the file with mv:


> mkdir temp
> mv x.txt temp/x.txt
> ls temp
x.txt
> ls
temp


Let's make the file `x.txt` actually do something, e.g.:


> echo "echo xyz" > temp/x.txt
> cat temp/x.txt
echo xyz
> sh temp/x.txt
xyz


Note that we wrote over the previous contents of temp/x.txt and the file system did not warn us first. There is no way to recover from this if it was a mistake!

The sh command executes the text in the file you give it; in this case the output is familiar. Normally, we'd probably use the file extension .sh for such a script, but it's not required. (Even with Python scripts, the .py extension is only required if you want to import a module).

We can also use the she-bang thing (#!) to make the code in a file executable. Use TextEdit to save the following code in a file y.txt on the Desktop:


#! sh
echo abc


Then we do the following. An executable can be executed just by entering its path, but.. there is a restriction that you can't do that for a program in the current directory. You must specify it as the relative path from the directory where we are currently./executable where the `.` means this directory (the restriction has never made a lot of sense to me either, but it's apparently a security hole):


> cat y.txt
#! sh
echo abc
> ./y.txt
-bash: ./y.txt: Permission denied


What has happened? We need to make the file "executable" by setting the "permission bits." Without getting into too much detail, these are output using a new option with the ls command:


> ls -l y.txt
-rw-r--r-- 1 telliott staff 19 Jan 30 20:08 y.txt
> chmod 711 y.txt
> ls -l y.txt
-rwx--x--x 1 telliott staff 19 Jan 30 20:08 y.txt
> ./y.txt
abc


The three permissions are r (read), w (write) and x (execute), listed in order for the user, her group, and the world. 7 is all of them. `x` is 1, `w` is 2, `r` is 4, and the combinations result from addition.

There are various shorthands for this. First reverting the previous change, then we could do this:


> chmod 644 y.txt
> chmod u+x y.txt
> ls -l y.txt
-rwxr--r-- 1 telliott staff 19 Jan 30 20:08 y.txt


We have given the user (only) permission to execute the file.


> ls -l ~/Desktop
total 1
drwxr-xr-x 2 telliott staff 102 Jan 30 20:08 temp
-rw-r--r-- 1 telliott staff 15 Jan 30 20:08 y.txt


When we do ls on the Desktop directory (above), we get a listing for both the temp sub-directory and the file. Note that the first character in the "file mode" is d for the directory. staff is my group name, and after that comes the number of bytes in each "file", including directories.

From man ls

The Long Format
If the -l option is given, the following informa-
tion is displayed for each file: file mode, num-
ber of links, owner name, group name, number of
bytes in the file, abbreviated month, day-of-
month file was last modified, hour file last mod-
ified, minute file last modified, and the path-
name. In addition, for each directory whose con-
tents are displayed, the total number of 512-byte
blocks used by the files in the directory is dis-
played on a line by itself, immediately before
the information for the files in the directory.
If the file or directory has extended attributes,
the permissions field printed by the -l option is
followed by a '@' character. Otherwise, if the
file or directory has extended security informa-
tion (such as an access control list), the per-
missions field printed by the -l option is fol-
lowed by a '+' character.


And finally, ls also has a recursive option, which can be grouped into -lR:


> ls -lR
total 8
drwxr-xr-x 3 telliott_admin staff 102 Jan 31 06:59 temp
-rw-r--r-- 1 telliott_admin staff 15 Jan 31 07:00 y.txt

./temp:
total 8
-rw-r--r-- 1 telliott_admin staff 4 Jan 31 06:59 x.txt


Let's continue by copying this file into our temp directory:


> cp y.txt temp
> ls
temp y.txt
> ls temp
x.txt y.txt


On the other hand, mv actually "moves" the file:


> mv y.txt temp
> ls
temp
> ls temp
x.txt y.txt


Once again, note the lack of warnings. The old copies of y.txt on the Desktop (and in temp) are gone forever.

Eventually, we tire of this. First we try to delete a single file:


> rm temp/y.txt
> ls temp
x.txt


But maybe temp has lots of files, so we try:


> rmdir temp
rmdir: temp: Directory not empty
> rm -r temp
> ls
>


The `-r` option is really dangerous. The classic Unix "joke" is to tell someone to do some combination of rm and -r and *. Don't fall for it.

You might think about looking at the man page for rm and maybe using the -i option.