From the last lecture we learnt to write our first C program and look at the compiler (gcc) code chain. We also got a demo on the garcia robot and discussed its architecture and a little about the project goals. More on that later in the term.
In this lecture, we will discuss the Linux shell and its commands. The shell is a command line interpreter and invokes kernel level commands. It also can be used as a scripting language to design your own utilities. We will discuss scripting as part a future lecture on shell programming.
Since we do not recommend you buy a Linux book here are some very good references and free access online books.
This is an excellent online version of the Linux manuals which are searchable web pages.
We plan to learn the following from today’s lecture:
OK. Let’s get started.
The shell is the Linux command line interpreter. It provides and interface between the user and the kernel and executes programs called commands. For example, if a use enters ls then the shell executes the command ls. The shell can also execute other programs such as applications, scripts, and user programs (e.g., written in c or the shell programming language).
You will get by in the course by becoming familiar with a subset of the Linux commands.
Linux has often been criticised for being very terse (it’s rumored that its designers were bad typists). Many commands have short, cryptic names - vowels are a rarity:
awk, cat, cp, cd, chmod, grep, find, ls, mv, ps, rm
|
We will learn to use all of these commands and more.
Linux command output is also very terse - the default action on success is silence. Only errors are reported. Linux strongly supports the philosophy of one and only one way to perform each task. Linux commands are often termed tools or utilities - familiarity with the “top 20” will be a great help.
Instructions entered in response to the shell prompt have the following syntax:
command [arg1] [arg2] .. [argn]
|
The brackets [] indicate that the arguments are optional. Many commands can be executed with or without arguments. Others require arguments (e.g., cp sort.c anothersort.c) to work correctly, if not, they will provide some error status message in return. But to avoid an explosion in the number of commands most commands support switches (i.e., options) to modify the actions of the commands.
For example, lets use the ls command and the -l option switch to list in long format the file c.tex. Switches are often single characters preceded by a hyphen (e.g., -l). Most commands accept switches in any order though they must appear before all “true” arguments (usually filenames). In the case of the ls example below the command arguments represent [options] filenames[s], as shown below. Options therefore modify the operation of the command and are operated on by the program called by the shell and not the shell itself.
In fact, the command is argument 0 (ls), -l switch or option is argument 1 and the filename is argument 2. Some commands also accept their switches grouped together. For example, the following switches to ls are identical:
[campbell@galehead lectures]$ ls -rtl
... [campbell@galehead lectures]$ ls -l -r - t |
The shell parses the words or tokens (commandname , options, filesnames[s]) and gets the kernel to execute the commands assuming the syntax is good.
Typically, the shell processes the complete line after a carriage return (cr) (carriage return) is entered and finds the program that the command line is wants executing. The shell looks for the command to execute either in the specified directory if given (./mycommnd) or it searches through a list of directories depending on your $PATH variable.
You will need to look at your $PATH variable and update it from time to time to make sure the path to the code you want to execute is there. Typically, your login files that execute when you log in (.bash˙profile) or each time to execute a command (.bashrc) are the place to set up these environment variables such as $PATH.
echo $PATH
/sw/bin:/sw/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/texbin:/sw/bin:/usr/X11R6/bin |
So where does the ls command executed above reside in the Linux directory hierarchy. Lets use another command to find out.
[atc@Macintosh-7 atc]$ which ls
ls is /bin/ls [atc@Macintosh-7 atc]$ whereis ls /bin/ls [atc@Macintosh-7 atc]$ |
The whereis or which commands are a useful sanity check if you want to know for sure which ls command is executed. For example, I could have wrote a program called ls and placed it in my working directory - probably not a good idea but could happen. In that case if I entered ls which command would the shell execute?
So we can see from the $PATH variable that /bin is in the path. Hence the shell can track down the ls binary to execute. The fact that the ls command is in /bin assumes that the filename /bin/ls has the correct permission set to be an executable by all. We can check this.
[atc@Macintosh-7 atc]$ ls -l /bin/ls
-r-xr-xr-x 1 root wheel 60972 Oct 17 2006 /bin/ls |
Indeed it is. The file is owned by “root” and is executable by all.
If I set my $PATH variable to “.” only the current working directory and execute ls (this would be akin to not having my path name set up correctly) then the shell would not be able to find the correct program to execute (assuming I don’t have an ls binary with the correct permissions in my current directory). Here is what would happen.
[atc@Macintosh-7 teaching]$ which ls
ls is /bin/ls [atc@Macintosh-7 teaching]$ PATH=. [atc@Macintosh-7 teaching]$ ls -bash: ls: command not found [atc@Macintosh-7 teaching]$ which ls -bash: type: ls: not found [atc@Macintosh-7 teaching]$ |
You may come across this error (“-bash: ls: command not found” or variants thereof) when you install code or try and execute new programs you want to use or have written.
There are a number of shells available to a Linux user - so which one do you select? These are:
We will be using the bash shell in this course since it is standard fair with Linux machines. Let’s check what shell has been configured for your login account. If it’s not the bash shell then let’s change the shell using the change shell chsh command. To find out what shell is running, log in and look at the $SHELL environment variable. We will use the echo command which is akin to the print (e.g., printf in C) statement in many languages.
[campbell@moose ~]$ echo $SHELL
/bin/tcsh [campbell@moose ~]$ chsh please login to galehead and run /usr/bin/chsh from there. [campbell@moose ~]$ ssh galehead campbell@galehead’s password: Last login: Sun Dec 23 22:58:58 2007 from moose.cs.dartmouth.edu [campbell@galehead ~]$ chsh -l /bin/bash /bin/sh /bin/ash /bin/bsh /bin/tcsh /bin/csh /usr/local/bin/bash /usr/local/bin/tcsh /bin/bash2 /bin/zsh |
The tsch shell is set. So we need to change the shell to bash. Note, that galehead is the only machine that you can change user configuration information on such as passwords and shells. So we ssh to galehead and list all permissible shells supported by our local Linux machines using the “chsh -l” switch.
Now, let’s change the shell to bash. Note, that our first attempt fails because the shell wants the full path name. We will discuss full and relative path names later in this lecture. Our second attempt using the full path name from above is successful.
[campbell@galehead ~]$ chsh -s bash
Changing shell for campbell. Password: chsh: shell must be a full path name. [campbell@galehead ~]$ chsh -s /bin/bash Changing shell for campbell. Password: Shell changed. [campbell@galehead ~]$ ps PID TTY TIME CMD 22271 pts/1 00:00:00 bash 22345 pts/1 00:00:00 ps |
Another way to see what shell is running is to use the process status (ps) command. We can see that the bash shell is running. The process ID and other status information of the process is displayed.
Note, that most commands executed by the shell starts a new “process”. (There is an exception to for for what are called builtins). We will discuss processes in a future lecture.
The basic shell operation is as follows. The shell parses the command line and finds the program to execute. It passes any options and arguments to the program as part of a new process for the command such as ps above. While the process is running ps above the shell waits for the process to complete. The shell is in a sleep state. When the program completes it passes its exit status back to the shell. At this point the shell wakes up and prompts the user for another command. Note, that it is the program that is executed, for example, ps in this case, that checks to see if the arguments passed to it by the shell are correct or not. It is not the job of the shell to do that level of parsing or error checking. If there are problems with the syntax (e.g., wrong switch) then it is the program itself that informs the user via an error message.
The term command and utility are used synonymous in these notes. The shell has a number of utilities built into the shell called builtins. When a builtin runs the shell does not fork a process; that is, it goes not create a process specifically to execute the command. Therefore, the builtins run more efficiently in the context of the existing process rather than having the cost of creating new processes to run the command. Typically users are not aware if a command runs as a builtin or a standard forked command. The echo command exists as a builtin to the shell and as a separate utility in /bin/echo. As a rule the shell will always execute a builtin before trying to find a command of the same name to fork. Bash supports a number of builtins including bg, fg, cd, kill, pwd, read among others.
The Linux file system is a hierarchical file system. The file system consists of a very small number of different file types. These include text files, directories, character special files (e.g., terminals) and block special files (e.g., disks and tapes).
A directory is just a special type of file. A directory (akin to a Macintosh folder) contains the names and locations of all files and directories below it. A directory always contains two special files ’.’ (dot) and ’..’ (dot dot). Every file has a filename of up to 1024 characters typically from ’A-Z a-z 0-9 ˙ .’ and an inode which uniquely identifies the file in the file system.
Directory names are separated by a slash ’/’, forming pathnames.
/usr/bin/emacs
/etc/passwd |
Files are accessed by referring to their relative or absolute pathnames.
Each account has a home directory. After you have logged in your shell will be executing in your home directory. So let’s log in and use the pwd command to find out where we are - we will be in the home directory of course.
[atc@Macintosh-7 l2]$ ssh -Y -l campbell moose.cs.dartmouth.edu
campbell@moose.cs.dartmouth.edu’s password: Last login: Mon Dec 24 11:37:01 2007 from c-75-69-130-98.hsd1.nh.comcast.net [campbell@moose ~]$ pwd /net/nusers/campbell |
Let’s list the contents of the home directory.
[campbell@moose ~]$ ls -l
total 434 drwx------ 2 campbell faculty 48 Dec 22 15:29 bin drwxr--r-- 5 campbell faculty 128 Dec 24 14:33 cs23 drwx------ 2 campbell faculty 48 Dec 22 15:30 lib drwx------ 3 campbell faculty 1368 Dec 24 11:25 mail drwx------ 3 campbell faculty 104 Nov 6 12:01 papers drwxr-xr-x 4 campbell ug 728 Oct 26 2006 public_html -rw------- 1 campbell faculty 435438 Dec 14 2006 Sent -rw------- 1 campbell faculty 1017 Mar 22 2007 Sent Messages drwx------ 3 campbell faculty 72 Dec 11 15:14 teaching |
Recall the “d” in “drwx——” indicates that this file is in fact a directory. So we can move to that directory assuming we have the relevant permission - which we do in all cases. So lets move around.
All files and directories have certain access permissions which constrain access to only those users having the correct permission. Let’s consider a couple of typical examples from above:
drwxr--r-- 5 campbell faculty 128 Dec 24 14:33 cs23
-rw------- 1 campbell faculty 1017 Mar 22 2007 Sent Messages |
The first character of the access permissions indicate what “type of file” is being displayed.
Following the first type of file character the next 3 triples (i.e., groups of three characters) from left to right represent file permissions: the read, write, and execute permissions, for (respectively) the owner (campbell in this case), the files’s group (faculty in this case), and the “rest-of-the-world”. To determine that group particular files are in enter the “ls -lg” command.
What do these permissions mean?
After the file permission comes the number of links to the file (e.g., 5), followed b the owner (campbell), group (faculty), size (e.g., 128) which represents the size of the file in bytes, date and time of modification (e.g., Dec 24 14:33), and the filename (e.g., cs23).
Note, that shellscripts (which we will discuss in a future lecture) must have both read and execute permission - bash or any of the shells must both be able to read the shellscript and execute it. Program binaries on the other hand do not need to be read and only need execution permission since they are not read but executed (recall when we tried to more a.out we could view it because it was an executable in machine code).
The permissions on files and directories may be changed with the chmod (change mode) command. When you own a file or directory you can use chmod to change the access permissions to the file or directory.
Only the three permission triplets may be changed - a directory cannot be changed into a plain file nor vice-versa.
Permissions given to chmod are either absolute or relative (i.e., symbolic).
Each triplet is the sum of the octal digits 4, 2, 1, and read from left to right. For example rwx is represented by 7, rw- by 6, and r– by 4 and so on The absolute octal values used with chmod are as follows:
The complete permission on any file is the sum of the values. For example, home directories are typically 700 which provides the owner with read, write, and execute permission but denies all access to others.
drwxr-xr-x 6 campbell faculty 152 Dec 31 20:40 cs23
... [campbell@galehead ~]$ chmod 700 cs23 ... drwx------ 6 campbell faculty 152 Dec 31 20:40 cs23 |
If you wish others to read your files set - in this case a file funny - then the command would be:
[campbell@galehead ~]$ chmod 664 funny
... -rw-rw-r-- 1 campbell faculty 0 Jan 1 15:50 funny |
Because the file is only to be read, not written too, and the fact that its a file with no execution (not a binary or shellscript) 644 makes good sense.
Use the manual pages to read how chmod can be used in a relative or symbolic mode can be used too; for example, what would
[atc@Macintosh-7 notes]$ chmod u=wrx,og-rwx cs23
|
These symbolic arguments need to be used carefully. Here “o” means others and “u” means owner or user.
“chmod o+wrx cs23” do?
The change directory command (cd) allows us to move around the Linux directory hierarchy. Let’s combine pwd, ls, and cd to move around the my local directories that are rooted at /net/nusers/campbell
[campbell@moose ~]$ cd cs23
[campbell@moose cs23]$ ls assignments code lectures [campbell@moose cs23]$ pwd /net/nusers/campbell/cs23 [campbell@moose cs23]$ cd lectures/ [campbell@moose lectures]$ ls bash-programming.tex design.tex se.tex start.tex c.tex linux-advance.tex shell.tex [campbell@moose lectures]$ pwd /net/nusers/campbell/cs23/lectures |
There are also a number of special characters that can be used with cd for short hand.
Moving to the parent directory:
[campbell@moose lectures]$ cd ..
[campbell@moose cs23]$ pwd /net/nusers/campbell/cs23 |
Moving back to where we came from:
[campbell@moose cs23]$ cd -
/net/nusers/campbell/cs23/lectures [campbell@moose lectures]$ pwd /net/nusers/campbell/cs23/lectures |
Moving to our home directory:
[campbell@moose lectures]$ cd ~
[campbell@moose ~]$ pwd /net/nusers/campbell |
and back:
[campbell@moose ~]$ cd -
/net/nusers/campbell/cs23/lectures |
campbell@moose lectures]$ ls -l
total 0 -rw-r--r-- 1 campbell faculty 0 Dec 24 12:22 bash-programming.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:22 c.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:23 design.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:22 linux-advance.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:23 se.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:21 shell.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:21 start.tex [campbell@moose lectures]$ |
Here are a popular set of switches you can use with ls:
-l list in long format (as above)
-t sort by modification time (latest first) -a list all entries (including ’dot’ files) -r list in reverse order (alphabetical or time) -R list the directory and its subdirectories recursively |
We can use a number of special characters to look at the files in a smart and efficient manner:
[campbell@moose lectures]$ ls -l s*
-rw-r--r-- 1 campbell faculty 0 Dec 24 12:23 se.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:21 shell.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:21 start.tex [campbell@moose lectures]$ |
[campbell@moose lectures]$ ls -l *s*
-rw-r--r-- 1 campbell faculty 0 Dec 24 12:22 bash-programming.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:23 design.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:23 se.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:21 shell.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:21 start.tex [campbell@moose lectures]$ |
[campbell@moose lectures]$ ls -l *.tex
-rw-r--r-- 1 campbell faculty 0 Dec 24 12:22 bash-programming.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:22 c.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:23 design.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:22 linux-advance.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:23 se.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:21 shell.tex -rw-r--r-- 1 campbell faculty 0 Dec 24 12:21 start.tex [campbell@moose lectures]$ |
In the following sequence we will create a new directory, create two new files (using touch), move one file to another directory, delete the other file and remove the directory.
[campbell@moose cs23]$ pwd /net/nusers/campbell/cs23 [campbell@moose cs23]$ mkdir project [campbell@moose cs23]$ cd project [campbell@moose project]$ touch socket.c transport.c [campbell@moose project]$ ls socket.c transport.c [campbell@moose project]$ mv transport.c ~/. [campbell@moose cs23]$ alias rm alias rm=’rm -i’ [campbell@moose project]$ alias rm=rm [campbell@moose project]$ rm socket.c [campbell@moose project]$ ls [campbell@moose project]$ cd .. [campbell@moose cs23]$ ls assignments code lectures project [campbell@moose cs23]$ rmdir project |
In the sequence above we reset the alias for rm which is set up in .bashrc. When you use the “rm -i” option the shell will ask you to confirm if you really want to delete files. This is worth doing by setting up the alias in your .bashrc file. It is ease to type “rm” and accidently delete files. Therefore, the “-i” (interactive) option is a life saver. For example,
[campbell@moose project]$ rm -i socket.c
rm: remove regular empty file ‘socket.c’? y |
In our home directory there are a number of interesting “hidden” files. Using the “-a” lists all files including those that begin with a dot (aka the hidden files).
[campbell@moose ~]$ ls -al
total 899 drwxr-xr-x 21 campbell faculty 1448 Dec 24 14:58 . drwxr-xr-x 25 root root 624 May 31 2007 .. -rw-r--r-- 1 campbell faculty 0 Dec 23 18:45 .addressbook -rw------- 1 campbell faculty 2285 Dec 23 18:45 .addressbook.lu drwxr-xr-x 3 campbell faculty 72 Nov 6 22:57 .adobe -rw------- 1 campbell faculty 4978 Dec 24 13:39 .bash_history -rw-r--r-- 1 campbell ug 882 Jun 24 1997 .bash_logout -rw-r--r-- 1 campbell faculty 1707 Dec 22 18:52 .bash_profile -rw-r--r-- 1 campbell faculty 1411 Dec 22 19:18 .bashrc ... (snip) -rw------- 1 campbell faculty 864 Dec 23 22:42 .Xauthority drwx------ 2 campbell faculty 136 Nov 5 21:04 .xemacs |
But a simple ls will only show:
[campbell@moose ~]$ ls
bin cs23 lib mail papers public_html Sent Sent Messages teaching |
Please read this material before the next class on Friday:
Philosophy (15 pages), chapter 1 of The Art of Unix Programming, by Eric S. Raymond.
The Perils of JavaSchools, (3 pages), by Joel Spolsky, December 29, 2005, an extract from Joel on Software.
Since we do not recommend you buy a Linux book here are some very good references and free access online books.