CS 279 - Week 7 Lecture 1 - 2022-10-03

TODAY WE WILL:
*   announcements
*   continuing intro to processes and jobs
*   standard files and redirection
*   prep for next class

=====
*   hey, bash has a while loop!

    while [ ...test ...]
    do
        ...
    done

=====
bit more in our intro to processes and jobs:
=====
*   we've talked about using the exit command
    to exit a shell script early -- say because
    of a lack of proper command-line arguments

*   THREE possible outcomes of calling a process:
    *   it can SUCCEED
    *   it can FAIL
    *   it can TERMINATE ABNORMALLY

*   how can you know which of these has happened?
    *   the EXIT STATUS of the process is a number that
        reveals this outcome

*   a process can terminate normally of its own accord,
    returning an exit status to its parent process
    *   UNIX/Linux: an exit status of 0 indicates success!
        (the process accomplished its desired task)

    *   another other exit status indicates failure --
        some processes will return a different non-zero status
	depending on the nature of the failure

        ...might be a way tell or warn the parent of something
	unexpected;

    *   convention: a process exiting with a failure status
        should return an exit status > 0 and < 128

        (because SIGNALS indicating abnormal termination
	start at 128 on up!)

*   Signals? ...a signal is something that can be sent to
    a process, and the process may or may not choose to
    respond to that signal

    [recall: ^letter means type control key and that letter at the
    same time]

    *   when we talked about typing ^Z to try to put a
        foreground process into the background,
	typing ^Z sends a signal to the foreground process;

        in the case of ^Z, system tries to send an interrupt
	signal;

    *   when a process happens to terminate abnormally,
        it cannot itself return an exit status,
	SO the UNIX/Linux kernel will return an exit status
	on its behalf, indicating why it terminated;

	*   the exit status in this case it is 128 +
	    the signal code number

        *   SIGKILL - 137
	etc.!

=====
*   oh right! A process in the background can be RUNNING, or
    it can be STOPPED (suspended)

    *   you can have a background job that is quietly running
        while in the background (not every process in the
	background is stopped);

    *   a stopped job is in a state of suspendedness --
        it remains dormant until you take action to resume it

*   we know the output of the jobs command marks the
    current job (most recently suspended or initiated)
    with a +

    *   if there are any stopped jobs, the current job is
        the one stopped most recently

    *   otherwise, the current job, if any, is the background
        job most recently suspended or initiated

        *   yes, a stopped job gets "priority" to a job
	    jusrt running in the background;

    *   (and if there are NO background or stopped jobs,
        the current job is undefined)

=====
*   recall: you can start a job in the background by
    ending a command with &

    *   in theory then, we should see those jobs
        having status "Running"

    *   but, when we tried:

        $ nano hey &
	$ top &

        ...we saw their status as "Stopped" in the jobs command:

MacBook-Pro:279lect07-1 smtuttle$ jobs
[1]-  Stopped                 nano hey
[2]+  Stopped                 top

        ...why?

    *   because these jobs attempted to read from the termina
        or write to the terminal,

        and if the terminal process has a setting tostop
	enabled,
	then trying to do these actions causes that process
	to be suspended; (and so they show as Stopped)

        *   can tostop be disabled?
	    YES, and then the output of the background job
	    is INTERMINGLED with the output of the foreground
	    job...!

    *   fun facts:
        *   if a background job attempts to read from a terminal,
	    it is sent the signal SIGTTIN  < tt for terminal type, and
	                                     in for input

        *   if a background job attempts to write to a terminal,
	    it is sent the signal SIGTTOU  < tt for terminal type, and
	                                     ou for output

        *   a program CAN adjust its behavior by TRAPPING these
	    signals and RESPONDING to them

=====
*   by the way: when a job TERMINATES or CHANGES STATUS in some way,
    the shell NOTIFIES you of the change RIGHT before it issues
    the next command prompt

=====
TIME FOR PIPES!!!!!!
=====
*   You can use the output of ONE command as the INPUT to another
    by typing the two commands separated by a vertical bar, |,
    called a pipe in UNIX/Linux

    *   useful! so much so that many programs intended for UNIX/Linux
        use accept standard input and output to standard output,
	so they are pipe-friendly!!

    *   EXAMPLES:

        *   piping a command with MUCH output to more!

            ps x | more

        *   yeah, we will see additional examples of this!

=====
*   oops, some more commands!

    sort - to sort its standard input, see the man page for more

    grep - general regular expression parser --
           lets you search for lines within specified files
	   that meet a pattern
	   ^ we are coming back to MORE patterns soon!

           grep "REU" *.docx
	   ...returns the lines of files ending in .docx
	   thst contain the pattern REU within them

=====
*   so I can type something like:

    (ps x | grep emacs | sort > looky) &

=====
*   recall: commands like kill or fg or bg can accept
    a jobs number as a possible input, if typed with
    the right syntax

    %n    - job number n
    %str  - unique job that begins with str
    %?str - unique job whose string CONTAINS the string str
    %+    - the current job
    %%      also the current job
    %-    - the previous job (the one with - in the jobs command)

=====
*   there's also a bg command!

*   You can often stop a foreground job if there is one by sending it
    a SIGSTOP signal, making it a background job and changing its
    status to Stopped
    *   usual way to do this: type the suspend character, normally ^Z

    *   to restart a stopped job AS A RUNNING BACKGROUND JOB,
        you can use the bg command

        (fg would restart it as the foreground job...)

*   fun fact: the kill command sends a SIGKILL signal...

=====
aside: source command
=====
*   we've seen: running a shell script runs it in its
    own little shell

    demo: run the little shell jobs-demo.sh, that
    little new shell does not have jobs associated with it,
    even though its parent shell did

*   you CAN ask for a shell script to be run in the
    CURRENT shell, using the source command:

    source desired_shell

    so, now:

    $ source jobs-demo.sh

    ...you WILL see the current shell's jobs!

    (and variables set in such a sourced shell WILL be
    reachable afterwards in the calling shell!)

====
*   one last bit for today:

    environment variable PS1 allows you to customize your
    bash shell prompt

    (yes, resetting it then changes your prompt!)

    (are many special character options for customizing
    this!)