Added io redirection and variables sections
authorEdgar Bering <ebering@csclub.uwaterloo.ca>
Wed, 6 Aug 2008 04:28:52 +0000 (00:28 -0400)
committerEdgar Bering <ebering@csclub.uwaterloo.ca>
Wed, 6 Aug 2008 04:28:52 +0000 (00:28 -0400)
holy-fuck-a-shell.pod

index 8fd8aa2..854730e 100644 (file)
@@ -420,12 +420,178 @@ 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
+
+will print information about every process with mysql somewhere in its
+information (usually things run by the mysql user or mysql client processes).
+
+=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 Its a programming language? Wheres while and friends?
+
 =for commentary
 
 Now I have to write this fucking section. Subsections:
-IO Redirection and the Pipe
-Variables, Environment Variables
 Loops and conditionals
 Scripts and arguments for them
+Customizing the shell to make it your shell
 
 =cut