\*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. Navigation ---------- A shell is *stateful*, tracking your current location and environment variables. Your location is a directory in on your file system. The ``pwd`` command prints your current working directory.:: $ pwd /home/prsteele This tells me my shell is working in the ``/home/prsteele`` directory, my *home directory*. To navigate to a new directory, use the ``cd`` command. The ``cd`` command takes a single argument. To move to the directory containing this file from my home directory, I would run:: $ cd Documents/Courses/orie-6125-sp2016/doc/unix If I weren't in my home directory, I could instead run:: $ cd ~/Documents/Courses/orie-6125-sp2016/doc/unix Here ``~`` expands to my home directory path, so that command was equivalent to:: $ cd /home/prsteele/Documents/Courses/orie-6125-sp2016/doc/unix 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 ------------ .. figure:: tar.png https://xkcd.com/1168/ 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. .. LocalWords: stdin stdout stderr