merging mgregson's patch to the ssh section and minor typos
[kspaans/UnixTutorial] / holy-fuck-a-shell.pod
index 7af4ba3..337ad1b 100644 (file)
@@ -11,20 +11,18 @@ practice one can control a computer with the skill of a poet.
 =head2 A few useful keys before we begin
 
 As you've probably guessed the shell is a command line interface that
-you type into. Its essentially an interactive programming language,
+you type into. It's essentially an interactive programming language,
 like the interactions window in DrScheme, but designed to operate on
 the system and work in a rather diverse environment. Its also designed
-for convinence, and as you'll discover quite powerful. Before we get
+for convinence, and as you'll discover, quite powerful. Before we get
 started there are a few keystrokes you'll need to be aware of.
 
-First, commands that you type in edit just like a line of text, you can
-scroll back and forth, use home and end keys, delete and backspace, etc.
-However its only one line, so the obvious question is what do up and down
-do? Well, they scroll back and foreward in your I<command history>, a log
-of everything you've done previous. Say you want to re-do something, just
-press up until the command you want re-appears. You can make small changes
-if you like, and if you go to far or want to get back to a blank line just
-scroll back down with the down arrow.
+First, the commands that you type in can be editted, similar to a line of
+text in a text editor.  You can move the cursor left and right, erase text
+(both delete and backspace work as you're familiar with from your word
+processor, and ctrl+k will delete everything to the right of the cursor),
+and scroll through your I<command history> (using the up arrow and down
+arrow for back and forwards respctively).
 
 If you want to view your command history use the command C<history>. To run
 an old command type C<!number> where number is the number next to the 
@@ -32,39 +30,56 @@ command in history.
 
 Most shells also provide tab completion of commands and file names, to
 use this just press tab after typing part of a file path or command, as long
-as its unique. If its not the shell will show you all the possibilities.
+as it's unique. If it's not the shell will show you all the possibilities
+(this may be a rather long list).
 
 =head2 Getting to the Shell
 
 There are several ways to access the shell remotely and locally. Remote
 shells can be obtained by connecting to a server with a program called
 Secure Shell or ssh. If you're local to a linux or unix system just start
-any of the many terminal programs.
+any of the many terminal programs. (On OS-X, look for Terminal in
+Applications>Utilities.  On Ubuntu look in the Applications menu under
+Accessories.)
 
 =head3 From Windows
 
+Unlike the other operating systems discussed here, Windows does not have
+a built in Unix-like shell.  There are several applications that provide
+Unix-like shell features on Windows, but the
+
 There are several utilities that can provide access to ssh from Windows, 
 the main one used by people at Waterloo is PuTTY 
-L<http://www.chiark.greenend.org.uk/~sgtatham/putty/>.
+L<http://www.chiark.greenend.org.uk/~sgtatham/putty/>. There is also a
+program called Cygwin L<http://cygwin.org>. It provides a Linux-like
+environment in Windows. You use it inside of a command-prompt window. So it's
+just like using PuTTY, except you don't have to be online to use it. Make sure
+the ssh package is installed, and then just type ssh.
 
 =for commentary
 
-ebering doesn't like writing about windows, someone else can do this shit
+What exactly did you want this to discuss? --mgregson
+
+This is fine --ebering
 
 =cut
 
-=head3 From Mac OSX
+=head3 From Mac OS-X
 
 Mac OS X comes with X11 (more on X11 later) installed, and with X11 comes
 a unix shell with most of the features discussed here, including an 
-ssh client. To access the student environment open X11 and open a terminal and
-use ssh just like in the linux section. You can also use many of the non
-student environment commands on your mac.
+ssh client. There is also a Terminal.app that you
+can find in /Applications/Utilities. It doesn't require that you start X11, but
+then you don't get the advantage of X11 forwarding. But that's an advanced
+topic that will be discussed later. You can also use many of the non student
+environment commands on your mac. Like most Unix-like operating systems, OS-X 
+comes with a built in ssh client. All you need to do to connect using SSH is to 
+open up Terminal and type in ssh user@host.  (Go on, give it a try.)
 
 =head3 From Linux
 
 To connect to the student environment from linux just start a terminal program
-and use ssh like on a mac, ssh will be documented in its own section. Also
+and use ssh like on OS-X, ssh will be documented in its own section. Also
 most of the things in this guide are useable on your local terminal as well.
 
 =head3 ssh(1) 
@@ -101,17 +116,16 @@ following:
  Your public key has been saved in ~/.ssh/id_rsa.pub.
  The key fingerprint is:
  <some numbers> user@host
- $scp ~/id*.pub user@host:~/ 
+ $ssh-copy-id user@host
  user@host's password: 
- id_rsa.pub
- id_dsa.pub
- $ssh user@host
- user@host's password:
- user@host$cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
- user@host$cat ~/id_dsa.pub >> ~/.ssh/authorized_keys
 
 This is optional and more detail can be found in the man page. More
-on those next...
+on those in the next section...
+
+Also, please keep in mind that while the passphrase can be, and too often is,
+left blank, this poses an enormous security risk and should only be done if
+you are 100% certain you are the only person who will be using the computer
+in question, and your hard drive is encrypted.
 
 =head2 Getting Help
 
@@ -144,18 +158,24 @@ for by default.
 
 We'll start with some basic file tools and command and control abilities.
 
+=for commentary
+
+Should we perhaps define "file system"?
+
+=cut
+
 =head2 The file system and what to do about it
 
 Programs are just files on disk and manipulate data which is also on the disk, 
 so it obviously follows that the most important programs are the ones for 
-working with files on the disk. This section will go over the filesystem and 
+working with files on the disk. This section will go over the file system and 
 these important programs.
 
-=head3 The filesystem is organized into directories
+=head3 The file system is organized into directories
 
 The file system in the unix environment starts with C</> or the root, different 
 drives are all attached as directories under the root. For now don't worry 
-about drives and lets chat about directories. In unix everything as a running 
+about drives and lets chat about directories. In unix everything has a running 
 or "working" directory, including your shell prompt. To see what your current 
 directory is use the B<p>rint B<w>orking B<d>irectory command C<pwd> at the 
 prompt. This will give you the I<absolute path> to your working directory. Any 
@@ -192,7 +212,7 @@ directory above the current directory. Here are some examples:
  /etc/config
  $cd network/
  $pwd
- /etc/config/netowrk
+ /etc/config/network
  $cd ..
  $pwd
  /etc/config
@@ -334,6 +354,15 @@ will be after the next section.
 A section on searching for files (even if its just a blurb) would be
 nice...
 
+mgregson--
+I'd recommend throwing in something about find.  It took me a while to figure
+out all the nice little tricks you can do with find, but it's definitely a
+worthwhile effort.
+
+eg: find ~/src -type f -iname "*.java" -exec grep "/*TODO:*" {} \;
+
+--mgregson
+
 =cut
 
 =head2 What the shell really gives you.. power.
@@ -346,13 +375,362 @@ shell that separate it from the gui, the programmable loops, variables that
 affect program execution, and io redirection. This section describes the
 machinary the shell provides to put words together to form ideas.
 
-=for commentary
+=head3 Every command you run is a process: how to run more than one.
+
+Every command you start from the shell (well there are a few exceptions we'll
+go in to in a bit) runs as a I<process>. In Unix processes represent separate
+discrete running programs, for example you can have several processes which 
+are all cp with different arguments (or the same arguments, but that is likely
+to break and not advised). In playing around with what you've learned in the
+last chapter you may have been frustrated by only being able to do one thing
+at a time. The shell does not limit you to running one thing at a time, and
+on the contrary gives you powerful tools for managing processes, both those 
+started by you and those already running on the system.
+
+For the purposes of I<job control>, processes can be viewed in two groups:
+those under the control of your shell (your I<jobs>), and those not. We'll
+first discuss the ways of starting your own jobs and interacting with them.
+
+=head4 Your jobs and what to do about them
+
+The first thing you're probably wondering is how to start more than one job.
+To do this you first need to know the difference between a I<foreground>
+process and a I<background> process. A foreground process is running attached
+to your terminal, your command prompt goes away and is replaced by its output 
+and any input goes to the program. With a program running in the background 
+it doesn't recieve input (unless you have an io redirect, more on that later)
+and output goes to your terminal, but you can still enter other commands.
+
+Before we can get to fancier features you probably want to know how to stop
+something in the foreground. To I<interrupt> or B<c>ancell the job in the
+foreground press C<CTRL+C> (hereafter C<control> will be abreviated with C<^>
+followed by a character. So C<CTRL+C> is C<^C> and so on and so forth). If you
+want to pause the job instead of terminating it press C<^Z>. This stores the
+process in a stopped state and gives you your command prompt back. You'll also
+see a message that looks like
+
+ [1]+   Stopped         some command with args
+
+The number in square brackets is the job number, C<+> means the state has
+changed. This is followed by the new state and what job is being run. If you
+want to bring your job back to the foreground type C<fg %1> and your job will
+come back just as you left it. Not very interesting, but the next part is. If
+you want to let your job finish running in the I<background> while you do
+something else type C<bg %1> and your job will resume running, but you still
+have a prompt to use. If you know you want a command to run in the background
+and don't want to futz with C<^Z>ing it and then typing bg you can just put an
+C<&> at the end of your command like so:
+
+ $cp ~/giant_file.tar.gz /mnt/usbdrive &
+
+Note that the number 1 in C<%1> isn't special, its just the usual job number of
+your first job. It will be different if you have more jobs running. To get a
+list of your jobs type C<jobs>. This will have job numbers, states and what
+command is running.
+
+To terminate a job early or put one of your background in a "Stopped" state
+(and often to communicate with it in other ways) unix provides I<signals>. A
+signal is a numbered code sent to a process with a meaning defined by the
+system. Commonly used signals are terminate, C<TERM>; kill, C<KILL>; and stop, 
+C<STOP>. C<TERM> instructs a process to stop what its doing and quit, C<KILL>
+ends it, and C<STOP> is equivalent to C<^Z>. Yes, C<^C> has a corresponding
+signal: interrupt, C<INT>. To send signals to jobs use the C<kill> command.
+By defaul C<kill> sends the C<TERM> signal, to specify other ones use C<-s>
+followed by the signal name. You also need to tell C<kill> which job to send
+the signal to.
+
+=head4 Other processes
+
+You may be wondering about the mention of processes not started by your shell.
+These all have associated numbers, called a I<process id>. Your jobs also have
+pids, and kill will take a pid instead of a job id. To see a listing of current
+processes use the command C<ps>. This will give all sorts of information:
+the pid, who started it, the attached terminal, whats running, the ram usage.
+C<ps> gets more useful when you're using more than one terminal or performing
+system administration.
+
+=head3 Input, output, and the story of a plumber
+
+As stated earlier processes running take input from standard input (your
+keyboard) and send it to standard output (your terminal) or errors to standard
+error (also your terminal). Sometimes this can be really inconvinent or down 
+right aggravating. Fortunatly the shell has an answer, its called 
+I<IO redirection>. This is the process of sending output somewhere other than
+your terminal and getting it from somewhere other than your keyboard.
+
+=head4 Simple redirection
+
+Simple redirection sends program output to a file or brings input in from a
+file. To connect input to a file use the C< < > character followed by a
+file name like this:
+
+ $mysql < lots_of_sql_queries.sql
+
+Output goes the other way, so naturally you use C<< > >> to send output to a file.
+By default one C<< > >> overwrites a file, for output to append you must add a
+second C<< > >>. Before going further, a word on I<file descriptors>. In unix when
+a file is opened by the system the open file handle isn't attached directly to
+the file on disk, but to a file descriptor, which is a number that the process
+can use internaly. File descriptors are also used by interpreted scripts, which
+when executed start an interpreter. Instead of passing the interpreter the
+filename (which could have been changed to do nasty things if someone is up
+to no good) the system passes the interpreter the file descriptor of an open
+handle to that file, as these are process specific and much harder to muck
+with. Normally you don't have to worry about file descriptors, but when
+redirecting input and output its nice to be aware of 3 of them. These are fds
+0,1, and 2, which correspond to standard in, standard out, and standard error
+respectively.  The left sides of C<< < >>, C<< > >>, C<<< >> >>> all take an
+implicit fd argument, 0 for the input operator and 1 for the output operators.
+To redirect standard error add a 2 in front of your operators. You can also
+redirect from one file descriptor to another using C<< i>&j >> to send output
+on fd i to fd j.
+
+File descriptors will be revisited when we discuss scripts, as you might have
+a need for more than the 3 default file descriptors there.
+
+You might be wondering if you can read from or write to other programs. Thats
+the topic of the next section, just remember with simple redirection you can't
+read from or send to programs.
+
+=head4 You mentioned plumbing? I don't see any pipes
+
+Actually, there are pipes in the shell, they are one of the most useful shell
+features. A pipe or pipeline is a way to connect standard out of one program
+to standard in of another. This is represented with the C<|> I<pipe> character.
+To demonstrate its power say you have a command that generates a lot of output,
+you don't really want to save it but you need to look at it, and it doesn't fit
+on one screen. Using what you know above you do this:
+
+ $massive-output > output.txt
+ $less output.txt
+ $rm output.txt
+
+Seems like a lot of work, since less by default reads from standard in. With
+pipes this mess gets shortened to:
+
+ $massive-output | less
+
+You can also chain pipelines using inbetween commands as filters, you can even
+use many of the commands that normally take files in pipelines using the
+special C<-> filename, consult the man pages for what you're using to get the
+specifics, a lot of commands take input from standard input by default. If you
+want to start the pipeline out with some text you enter you can put it in a
+file or you can use C<cat -> to send standard in to standard out. When you are
+done typing press C<^D> to send the End of File (EOF) character (Note not all
+control characters send signals).
+
+Chaining pipes was mentioned, this allows you to insert filters into the stream
+we'll go over a few useful ones now, though for more in depth coverage check
+the text editing tutorial.
+
+=over 8
+
+=item C<tee>
+
+C<tee> creates a split in a pipe, saving the output to a file (or multiple
+files) as well as passing it on standard out so the pipeline can continue.
+Useful for saving state or putting a T in your pipeline and starting the
+other branch with C<cat your_tee_savefile | rest_of_pipeline>.
+
+ $ command_pipeline | tee save_file | more_pipeline
+
+=item C<grep>
+
+C<grep>'s odd name comes from an antiquated unix editor and a common sequence
+of commands used to search. These commands are B<g>lobally, B<r>egular 
+B<e>xpression, B<p>rint, used to go through an entire file and print lines
+matching a pattern. For details on C<grep>'s pattern format check the text
+processing tutorial or the man page. C<grep> can be used on files but its 
+mentioned here as a filter. When used in a pipe it will filter whats coming
+in on the pipeline, outputting only what matches the pattern, for example:
+
+ $ps | grep mysql
 
-Now I have to write this fucking section. Subsections:
-Jobs and controlling them
-Variables, Environment Variables
-IO Redirection and the Pipe
-Loops and conditionals
-Scripts and arguments for them
+will print information about every process with mysql somewhere in its
+information (usually things run by the mysql user or mysql client processes).
 
-=cut
+=item C<sed>
+
+C<sed> stands for B<s>tream B<ed>itor, and provides powerful facilities for
+editing data as it comes in through a pipeline. C<sed> can also automate various
+other editing tasks. More information on C<sed> can be found in the editing
+tutorial.
+
+=item C<sort>
+
+C<sort> does exactly what you think it does, takes input, outputs a sorted
+version. The various options in the man page control different ways of sorting,
+but its not worth mentioning them here, as I'm sure you'll look it up when you
+actually need it instead of reading it now and forgetting it.
+
+=item C<uniq>
+
+C<uniq> takes input and outputs only the B<uniq>ue lines. A useful option is
+C<-c> which gives you a count of repitions.
+
+=item C<wc>
+
+C<wc> is a B<w>ord B<c>ounting program. It takes input and outputs the number
+of lines, words, and characters in the input. It will also take a file or many
+files and give you by file output as well as totals. You might write a version
+someday...
+
+=back
+
+=head3 Variables and the Environment (no you don't have to go green)
+
+At this point you may have guessed that the shell is infact an interactive
+programming language designed specifically for gluing other programs together
+and administering systems. If you did, you're right. If not, well it is, and
+like most programming languages it has support for variables. Variables in the
+shell come in two forms: locally scoped variables and I<environment> variables.
+Locally scoped variables are visible only to one command (commands may start
+multiple programs, see other parts of this chapter for how) while environment
+variables are visible to everything that runs as a child of your shell (unless
+otherwise specified, but we'll get to that).
+
+To set local variables just use C<=> in a statement, like:
+
+ $var="stuff";
+
+and to get values append a C<$> to the name and the shell will substitute it:
+
+ $echo $var
+
+(echo just prints out what you pass to it).
+
+Environment variables are global to your shell and allow you to customize
+various shell options and inform programs you start of your preferences for
+things like your pager and your prefered text editor. To get a full rundown
+of the available vars check out the manpage for C<environ(7)> (if you haven't
+read at least a bit of C<man man> yet the number is a manual section, and to
+specify it place it before the name of the page: C<man 7 environ>). To set new
+ones or modify your current ones use C<export> followed by your assignment
+statement, or just the variable name if you have it set already. If you're
+curious about what variables are already set just run C<export> without
+arguments.
+
+If you want environment variables to remain set in new sessions edit your
+F<.bash_profile> or F<.profile> file and add new lines with your export
+commands. For more on these files see the customizing your shell section.
+
+=head3 Scripting the shell
+
+Since the shell is really just an interactive programming language an obvious
+question is "does it have a non-interactive mode?". The answer is yes. This is
+called I<shell scripting> and is a useful way to automate repetitive tasks and
+add desired functionality. Since the interactive shell and the scripted shell
+are the same thing, features discussed here can be used at the prompt, though
+they may not be useful.
+
+Shell scripts consist of a series of shell commands on separate lines or
+separated by semicolons. To create one open an editor on a new file (call it
+whatever you like, by convention they have the C<.sh> extension) and enter
+the sequence of commands you wish to be able to run over and over again. Save
+the file and make sure you have permission to execute it. Then at the prompt
+type C<./your_file_name> to run it. 
+
+Scripts can also take arguments, these appear in variables C<$1> to C<$9>,
+(if you need more than nine place the numbers in braces). There are also some 
+useful special variables: C<$?> is the exit status of the last command run,
+an indicator of error conditions; C<$$> is the process id of the script, and
+C<$0> is the name of the script, which provide relevant information for error
+messages as well as the change of behavior based on script name or process id
+(the first one is sometimes used for startup/shutdown scripts, the second one
+is insane).
+
+
+=head3 Its a programming language? Wheres while and friends?
+
+Yes, the shell is an interactive programming language, and yes there are loops
+and conditional expressions. If you've ever used an imperitive programming
+language (like Java or VB or Perl) these first few should be familiar. These
+are going to be quick commentaries, for more info you can read the shell man
+page.
+
+=over
+
+=item C<if>
+
+If works just like you'd expect, except there are also a myriad of useful file
+test options to query the properties of files and file descriptors.
+
+ if [ -e "filename" ]; then 
+     echo "filename exists";
+ fi
+
+ if [ "$3" = "start" ]; then
+     echo "starting";
+ elif [ "$3" = "stop" ]; then
+     echo "stopping";
+ else
+     echo "option 3 invalid";
+ fi
+
+=item C<while>,C<until>
+
+While loops while a condition is true, until loops until a condition is true. 
+These are the same conditions used in if.
+
+ while [ -e "lockfile" ]; do
+     echo "waiting for lock to be released";
+     sleep 5;
+ done;
+
+ X=0
+ until [ $X = 20 ]; do
+     echo "zomgwtf";
+     X=$((X+1)) # arithmatic expression, read the man page. You probably
+                # want to use a real programming language for heavy iteration
+ done;
+
+=item C<for x in>
+
+While bash has a c style for loop, don't use it. You probably want a real
+programming language at that point. The useful for loop iterates through a
+list for you, setting x (or whatever other variable name you use) to the values
+one at a time. You can use a plain list, a file glob, or any command in
+backticks (which evaluates the command and substitutes the value).
+
+ # Backup git repositories in /backup/repos
+ for d in `ls -d /backup/repos`; do
+     cd $d;
+     git pull;
+ done;
+
+=back
+
+=head3 Customizing your shell
+
+Through this document we've been talking about "the shell". The fact is there
+are many, many, shells all with the standard features discussed here (and some
+without) as well as a variety of extensions and unique features.
+
+The shell used as a reference when writing this guide and a common default is
+C<bash>, B<B>ourne B<A>gain B<Sh>ell, also popular are C<ksh> (B<K>orn 
+B<Sh>ell), C<csh> (B<C> B<Sh>ell), C<tcsh> (an enhancement of C<csh>), and
+C<zsh> (the B<Z> B<Sh>ell, an addition of new features to a C<ksh> and C<bash>
+featrues). Feel free to experiment, you can start a new shell by invoking it as
+a command or using C<chsh> and logging out and in again.
+
+To set shell options and environment variables you can edit the various F<rc>
+and F<profile> files associated with your shell, check the man page for details
+on which files to edit.
+
+In these files you can also start background jobs if you'd like, though it is
+often more useful to have automated tasks. Many systems have a C<cron> program
+installed which can be used to run programs even when you aren't around, to
+add these edit a file called a F<crontab> using the progrogram with the same
+name to do so. Check the associated man page for syntax in the file and what
+you can and cannot run in it.
+
+=head2 About the Authors (when they wrote this)
+
+This document is maintained and copyright The University of Waterloo Computer
+Science Club 2008 and is released under the terms of the Artistic Liscence
+version 2.0 available at L<http://www.perlfoundation.org/artistic_license_2_0>.
+
+=head3 Edgar Bering (ebering@csclub.uwaterloo.ca)
+
+A student heading into his second year Edgar served as club secretary W08 and
+plans on running for executive most of the rest of the time he's around.