# The Linux programming environment

This chapter will introduce you to Linux, a Unix-like operating system called Linux. Most people run Unix with a command-line interface provided by a shell. Each line typed to the shell tells it what program to run (the first word in the line) and what arguments to give it (remaining words). The interpretation of the arguments is up to the program.

### The shell

The examples in this course assume you have bash, the Bourne-again shell written by the GNU project. Other shells behave similarly for basic commands.

### The Unix filesystem

Most of what one does with Unix programs is manipulate the filesystem. Unix files are unstructured blobs of data whose names are given by paths consisting of a sequence of directory names separated by slashes: for example /home/accts/some-user/cs223/hw1.c. At any time you are in a current working directory (type pwd to find out what it is and cd new-directory to change it). You can specify a file below the current working directory by giving just the last part of the pathname. The special directory names . and .. can also be used to refer to the current directory and its parent. So /home/accts/some-user/cs223/hw1.c is just hw1.c or ./hw1.c if your current working directory is /home/accts/some-user/cs223, cs223/hw1.c if your current working directory is /home/accts/some-user, and ../cs223/hw1.c if your current working directory is /home/accts/codeahoy-user/downloads.

### Unix command-line programs

Here are some handy Unix commands:

###### man

man program will show you the on-line documentation (the man page) for a program (e.g., try man man or man ls). Handy if you want to know what a program does. O

You can also use man function to see documentation for standard library functions. The command man -k string will search for man pages whose titles contain string.

Sometimes there is more than one man page with the same name. In this case man -k will distingiush them by different manual section numbers, e.g., printf (1) (a shell command) vs. printf (3) (a library routine). To get a man page from a specific section, use man section name, e.g. man 3 printf.

###### ls

ls lists all the files in the current directory. Some useful variants:

• ls /some/other/dir; list files in that directory instead.
• ls -l; long output format showing modification dates and owners.
###### mkdir

mkdir dir will create a new directory in the current directory named dir.

###### rmdir

rmdir dir deletes a directory. It only works on directories that contain no files.

###### cd

cd dir changes the current working directory. With no arguments, cd changes back to your home directory.

###### pwd

pwd (“print working directory”) shows what your current directory is.

###### mv

mv old-name new-name changes the name of a file. You can also use this to move files between directories.

###### cp

cp old-name new-name makes a copy of a file.

###### rm

rm file deletes a file. Deleted files cannot be recovered. Use this command carefully.

###### chmod

chmod changes the permissions on a file or directory. See the man page for the full details of how this works. Here are some common chmod’s:

• chmod 644 file; owner can read or write the file, others can only read it.
• chmod 600 file; owner can read or write the file, others can’t do anything with it.
• chmod 755 file; owner can read, write, or execute the file, others can read or execute it. This is typically used for programs or for directories (where the execute bit has the special meaning of letting somebody find files in the directory).
• chmod 700 file; owner can read, write, or execute the file, others can’t do anything with it.

### Stopping and interrupting programs

Sometimes you may have a running program that won’t die.

There are various control-key combinations you can type at a terminal window to interrupt or stop a running program.

###### ctrl-C

Interrupt the process. Many processes (including any program you write unless you trap SIGINT using the sigaction system call) will die instantly when you do this. Some won’t.

###### ctrl-Z

Suspend the process. This will leave a stopped process lying around. Type jobs to list all your stopped processes, fg to restart the last process (or fg %1 to start process %1 etc.), bg to keep running the stopped process in the background, kill %1 to attempt to end process %1 politely, kill -KILL %1 to end process %1 even if it is intercepting normal kills.

###### ctrl-D

Send end-of-file to the process. Useful if you are typing test input to a process that expects to get EOF eventually or writing programs using cat > program.c (not really recommended). For test input, you are often better putting it into a file and using input redirection (./program < test-input-file); this way you can redo the test after you fix the bugs it reveals.

###### ctrl-\

Quit the process. Sends a SIGQUIT, which asks a process to quit and dump core. Mostly useful if ctrl-C and ctrl-Z don’t work.

If you have a runaway process that you can’t get rid of otherwise, you can use ps g to get a list of all your processes and their process ids. The kill command can then be used on the offending process, e.g. kill -KILL 6666 if your evil process has process id 6666. Sometimes the killall command can simplify this procedure, e.g. killall -KILL evil halts all process with command name evil.

If you compile your own program, you will need to prefix it with ./ on the command line to tell the shell that you want to run a program in the current directory (called ‘.’) instead of one of the standard system directories. So for example, if I’ve just built a program called count, I can run it by typing

$./count  Here the “$ ” is standing in for whatever your prompt looks like; you should not type it.

Any words after the program name (separated by whitespace—spaces and/or tabs) are passed in as arguments to the program. Sometimes you may wish to pass more than one word as a single argument. You can do so by wrapping the argument in single quotes, as in

$./count 'this is the first argument' 'this is the second argument'  ### Redirecting input and output Some programs take input from standard input (typically the terminal). If you are doing a lot of testing, you will quickly become tired of typing test input at your program. You can tell the shell to redirect standard input from a file by putting the file name after a < symbol, like this: $ ./count < huge-input-file


A ‘>’ symbol is used to redirect standard output, in case you don’t want to read it as it flies by on your screen:

$./count < huge-input-file > huger-output-file  A useful file for both input and output is the special file /dev/null. As input, it looks like an empty file. As output, it eats any characters sent to it: $ ./sensory-deprivation-experiment < /dev/null > /dev/null


You can also pipe programs together, connecting the output of one to the input of the next. Good programs to put at the end of a pipe are head (eats all but the first ten lines), tail (eats all but the last ten lines), more (lets you page through the output by hitting the space bar, and tee (shows you the output but also saves a copy to a file). A typical command might be something like ./spew | more or ./slow-but-boring | tee boring-output. Pipes can consist of a long train of programs, each of which processes the output of the previous one and supplies the input to the next. A typical case might be:

###### yy

Like dd, but only saves the line to register "" and doesn’t delete it. (Think copy). All the variants of dd work with yy: 5yy, y\$, yj, y%, etc.

###### p

Pull whatever is in register "". (Think paste).

###### « and »

Outdent or indent the current line one tab stop.

###### :make

Run make in the current directory. You can also give it arguments, e.g., :make myprog, :make test. Use :cn to go to the next error if you get errors.

###### :!

Run a command, e.g., :! echo hello world or :! gdb myprogram. Returns to Vim when the command exits (control-C can sometimes be helpful if your command isn’t exiting when it should). This works best if you ran Vim from a shell window; it doesn’t work very well if Vim is running in its own window.

##### Insert mode
###### control-P and control-N

These are completion commands that attempt to expand a partial word to something it matches elsewhere in the buffer. So if you are a good person and have named a variable informativeVariableName instead of ivn, you can avoid having to type the entire word by typing inf if it’s the only word in your buffer that starts with inf.

###### control-O and control-I

Jump to the last cursor position before a big move / back to the place you jumped from.

###### ESC

Get out of insert mode!

###### Settings

Unlike Emacs, Vim’s default settings are not very good for editing C programs. You can fix this by creating a file called .vimrc in your home directory with the following commands:

set shiftwidth=4
set autoindent
set backup
set cindent
set hlsearch
set incsearch
set showmatch
set number
syntax on
filetype plugin on
filetype indent on


examples/sample.vimrc

In Vim, you can type e.g. :help backup to find out what each setting does. Note that because .vimrc starts with a ., it won’t be visible to ls unless you use ls -a or ls -A.
In this chapter, we introduced you to Linux, the bash` shell, important shell commands and couple of very popular text editors. In the next chapter, we’ll go through how to compile and debug C programs.