*nix¶
The phrase *nix refers to family of operating systems descended from Unix, e.g. GNU/Linux, Mac OSX, BSD... that share a common philosophy for how a computer should work. Ideally these operating systems obey the POSIX standard, and most do at least partially.
Shell¶
A (for our purposes, text-based) user interface to an operating system. A shell allows you to run programs and see their output. Common shells include:
bash
tsh
zsh
csh
fish
Terminal¶
A program (graphical or otherwise) that allows you to interact with a shell program.
Getting started¶
To get started, you should open a terminal (which will launch your
default shell, probably bash
). Do this like you would any other
program on your operating system of choice.
Running a program¶
To run a program in the shell, we simply enter the name of that program. For example, to run Python 3 we would write:
$ python3
Python 3.4.3+ (default, Oct 14 2015, 16:03:50)
[GCC 5.2.1 20151010] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
When we enter the name of a program to be run, the shell checks a list
of directories for an executable matching that name. We can ask which
program is being run with the which
command.:
$ which python3
/usr/bin/python3
This tells us the absolute path to the program we are running. This means we could instead run:
$ /usr/bin/python3
Python 3.4.3+ (default, Oct 14 2015, 16:03:50)
[GCC 5.2.1 20151010] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
The list of directories we search is found in the $PATH
environment variable. We can list the contents of an environment
variable with the echo
program.:
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:~/bin
We can see that $PATH
contains a colon-delimited list of
directories to search for a program to run. Note that the current
directory, .
, is not listed. If we created a program called
myprogram
in our home directory that we wanted to run and we ran
just myprogram
, we would get the following
$ myprogram myprogram: command not found
We would instead need to run:
$ ~/myprogram
Hello!
Since we specified a path to the program, we bypass searching $PATH
.
Managing files¶
One of the most common tasks in the shell is to look around to find
files, copy them, rename them, or delete them. We can see what is in
our current directory with the ls
program:
$ ls
Documents Downloads Music Pictures
(This is a greatly abbreviated listing.) We can of course look in different directories:
$ ls Downloads
3300.tex gurobi5.6.3_linux64.tar.gz
The cp
program copies files, while the mv
command moves or
renames files. They both use the same syntax.:
$ cp original-file copy-file
$ mv original-file new-file
The rm
command deletes files.:
$ rm new-file
Please use caution when running rm
, especially with flags such as
-r
or -f
, which causes rm
to recursively delete
sub-directories and fail to ask for confirmation when doing so,
respectively.
Input/output redirection¶
Each program has three ways to perform I/O: standard input, standard output, and standard error (abbreviated stdin, stdout, and stderr, respectively). Programs can read input from stdin and write output to either stdout or stderr. stdout is used for most output, while stderr is used to log errors. In a terminal, the text that shows up on your screen is from both stdout and stderr.
We can redirect stdout and stderr to files. To redirect stdout, we use
>
. To redirect stderr, we use 2>
.:
$ ls > list_of_files
$ ls 2> any_error_messages
Documents Downloads Music Pictures
- We can of course do both at the same time.::
- $ ls > list_of_files 2> any_error_messages
and even redirect both to the same file. Order matters, here.:
$ ls > list_of_files_and_errors 2>&1
We can also connect the stdout of one program to the stdin of the next.:
$ pwd | ls
is a contrived way to list the contents of the current directory. More useful would be something like:
$ ls -1 | grep '.*py$' | grep -v '^test_' | wc -l
This lists all files in the current directory, one per line, then
finds all lines that end in .py
, then removes all lines that begin
with test_
, and then counts the number of lines remaining. This
would be one way to count the number of Python files in the current
directory that don’t begin with test_
.
Another (more dangerous) command recursively removes all backup files
made by Emacs under the current directory, which are marked by a
trailing ~
.:
$ find . -name '*~' -print0 | xargs -0 rm
Getting help¶
The man
program displays the manual page for most programs (and C
and C++ header files).:
$ man git
shows a (perhaps not very useful) introduction to the git
program. If you were trying to figure out how to use ls
to print
more information about files,:
$ man ls
would teach you about the -1
, -a
, -l
, and -h
flags.:
$ man bash
will teach you that writing any non-trivial program in Bash is a nightmare.:
$ man man
might technically be enough for you to learn everything on this page without reading it.