layout: true
Class 4: Shells
--- class: center, middle # Class 4 --- class: center, middle # Shells ## feat. Bash ### `:(){ :|:& };:` #### Do __NOT__ run this --- # Overview 1. Announcements 2. Review + Exercises 3. Q&A 4. Basic assignment --- # Announcements * Unix assignments: February 15 * Shell assignments: February 21 * Unix survey closing today -- * Reference slides for each week! -- * Lunar New Year tomorrow! --- class: center, middle # Review --- # Review * Command grouping * `(commands)` * `{ commands; }` --- # Expansion ### Parameter expansion ("variable" expansion) * `$varname` * `${varname}` * `${varname:-[value]}`: use default value -- * Bash substring expansions * `${varname:offset}` * `${varname:offset:length}` --- # Expansion ### Filename expansion ("glob"/"wildcards") * Expand out to filepaths that match the pattern * `*`, `?`, and `[]` -- ### Command substitution (via subshell) * `$(command)`: substitute the output of a _command_ in the brackets -- * Q: `$logname` vs. `$(logname)`? --- # Expansion ### Arithmetic expansion * `$((expr))` will expand to an evaluated arithmetic expression _expr_ * Integer only -- ### Process substitution (Bash) * `<(command)` will substitute the _command_ output as a filepath, with the output of _command_ being __readable__ * `>(command)` will substitute the _command_ input as a filepath, with the input of _command_ being __writeable__ * `$ diff <(echo hello) <(echo olleh | rev)` * `diff` takes in two file names, but we're replacing them with "anonymous" files containing the command outputs --- ## Exercises 1. Assign a variable `greeting` to a string that is concatenation of the string "user:" and the `USER` variable 2. Write a `mv` command that moves all files in the current directory that end in `.txt` into a directory called `text` 3. Use a command substitution (`$(commands here)`) to get the output of `whoami` and save it into a variable `me` --- ## Quoting * Single quotes (`'`) preserves __all__ of the characters between them * Double quotes (`"`) preserve all characters except: `$`, `\`, and backtick --- ## Compound commands and control flow ### `if-elif-else` ```bash # '#' comments out the rest of the line # elif and else are optional parts if test-commands; then commands elif more-test-commands; then more-commands else alt-commands fi ``` * _test-commands_ is executed and its __exit status__ is used as the condition * ___0___ = success = "true", everything else is "false" --- ### Commands for conditionals * `test expr`: `test` command * `[ expr ]` (remember your spaces! `[` is technically a utility name) * `test $a -eq $b` * `[ $a -eq $b ]` * These set the exit status (`?`) to 0 (true) or 1 (false) * `[ $a -eq $b ] && [ $a -lt 100 ]` * `test $a -eq $b && test $a -lt 100` --- ### Commands for conditionals (Bash) * `[[ expr ]]`: __Bash__ conditional * Richer set of operators: `==`, `!=`, `<`, `>`, among others * __Note__: The symbol operators above operate on strings * `((expr))`: __Bash__ arithmetic conditional * Evaluates as an arithmetic expression * `(($a < $b))`: this would evaluate to "false" if a=100, b=2 --- ### `while` ```bash while test-commands; do commands done ``` * Similarly to `if`, the exit status of _test-commands_ is used as the conditional * Repeats _commands_ until the condition __fails__ -- ### `until` ```bash until test-commands; do commands done ``` * Repeats _commands_ until the condition __succeeds__ --- ### `for` ```bash for var in list; do commands done ``` * Each iteration _var_ will be set to each member of the _list_ * _list_ is simply a list of whitespace-delimited strings * _list_ will have any necessary expansions performed * __Note__: if there is no `in list`, it will implicitly iterate over the argument list (i.e. `$@`) * Example lists: * `1 2 3 4 5` * `$(ls)` * `$(seq 1 5)` --- ### `case` ```bash case value in pattern1 ) commands1 ;; pattern2 ) commands2 ;; multpat1 | multpat2 ) commands3 ;; * ) commands esac ``` * _value_ is matched against patterns * When a pattern is matched its command(-list) is run * A wildcard pattern is often used to represent a "default" case --- ## Exercises 1. Write an `if` statement that prints "success!" if the last command ran successfully * Remember the `?` variable? * `echo` can print text for you * `true` and `false` can give you a success and failure 2. Write a `for` loop that creates 5 files, named `file1` to `file5` * `seq 1 5` can produce a list of integers from 1 to 5 * `touch` can create empty files for you --- ## Functions ```bash func-name () compound-command # parens are mandatory # or function func-name () compound-command # [Bash]; parens are optional ``` * A __compound command__ is a __command group__ (`()`, `{}`) or a control flow element (`if-elif-else`, `for`) * Called by invoking them like any other utility, including __passing arguments__ * Arguments can be accessed via `$n`, where _n_ is the argument number * `$@`: list of arguments * `$#`: number of arguments --- ### Examples ```bash hello-world () { if echo "Hello world!"; then echo "This should print" fi } # calling hello-world ``` ```bash # Bash function touch-dir for x in $(ls); do touch $x; done # calling touch-dir ``` --- ```bash echo-args () { for x in $@; do echo $x done } # calling echo-args a b c d e f g ``` ```bash # Bash function divide { if (( $2 == 0 )); then echo "Error: divide by zero" 1>&2 # the redirection copies stderr to stdout so when echo # outputs it's really going to the caller's stderr else echo $(($1 / $2)) fi } # calling divide 10 2 divide 10 0 ``` --- # Configuring the shell * Shells will automatically source certain files to perform configuration * `/etc/profile`: system-wide configuration * `~/.bashrc`: Bash's user shell configuration file * `~/.zshrc`: Zsh's user shell configuration file -- * You can make your own additions to your `~/.bashrc` or `~/.zshrc` etc. * Maybe you want to add a directory to `PATH`? * `export PATH="newdir:$PATH"` * Maybe I want to alias a word to a command that navigates to my Windows side? * `alias cdw='cd /mnt/c/Users/brandon/'` * Maybe I want to change up my prompt?... * `PS1` variable --- class: center, middle # Q&A --- class: center, middle # Basic assignment