The Bash shell is both a command interpreter and a programming language.
The discussion of the shell internals may feel abstract at first. Return to it later after going through practical exercises. Did it help understanding the shell commands and scripts?
At its base, a shell is simply a macro processor that executes commands. It parses the command line (or a line of a script), makes variable expansions, etc, and finally, tries to execute the first word. The remaining words are arguments to the first (command).
We’ll return to etc in more detail later.
Command search: Have you ever seen ...: command not
found error? How does the shell search for commands?!?
A “command” can be a shell builtin, a shell keyword, an executable binary, an executable script, a shell function or a shell alias. These all behave almost the same.
Command types: Which commands can you use to find what a “command” more precisely is, and where it comes from? What is the precedence of different command types? For example, if you have a shell function and an executable binary with the same name, which one gets executed?
Every command returns an exit status value (0-255) to the calling shell. Value zero indicates success, and non-zero value indicates failure. It is up to the calling shell (script) to decide what to do with the exit status.
Special parameter $? expands to the status of the most recently executed
foregorund command (pipeline).
Six standard “channels”:
IN: 1) command arguments, 2) standard input stream (stdin), 3) environment variables
OUT: 1) standard output stream (stdout), 2) standard error stream (stderr), 3) command exit status
Command inputs and outputs: What are the conventions of using different input and output channels, what type of data is communicated through different channels? Give examples for using each.
As a working assumption, shell has two variable types, strings and arrays of
strings (and hash arrays, for Bash 4+). String variables may be exported to the
shell’s environment (see ENVIRONMENT chapter in man bash).
PARAMETERS, see man bash…Environment: How do you promote a variable to an environment variable?
TIP: When playing around, start a new subshell with command bash, and when you
are done, exit, and you are back in the original, unaltered environment.
Subshells: How do you run a command (or compound command!) in a sub-shell? Can you name situations when the shell creates a sub-shell?
Shells can be started in interactive or in non-interactive mode. In interactive mode, they accept input typed from the keyboard. When executing non-interactively, shells execute commands read from a file.
Shell initialization: Which shell initialization files are read (in your machine) when interactive/non-interactive shell is started? What initializations should go to which initialization file and why?
The shell performs the following actions, from left to right:
Command expansion: Explain why a=works echo $a does not work, but both a=works
bash -c 'echo $a' and a=works; echo $a work?
Expansion is a process of exchanging a word with another word(s), with certain rules. Bash performs following expansions (in order):
{...}~...$..., ${...}$((...))$(...)man bash and IFS*, ?, [...]Tip: Remember the set -x trick!
Quoting is used to control expansions, and word splitting
\ |
preserve the literal value of the next character |
'' |
preserve the literal value of each character within the quotes |
"" |
preserve the literal value of each character within the quotes, with the exception of $, `, and \ |
Quoting: …is pretty important. Can you guess what you get with file="file
name"; touch $file? Spaces in filenames is evil, the correct solution is to use
snake_case or CamelCase. Using double quotes is a good default when
expanding variables, unless you intentionally wish to expand a string variable
as separate words/arguments!
Signals are asynchronous notifications that are sent to processes when certain
events occur. Command trap allows you to catch signals and execute specified
code when a process receives a signal. Option -l lists all available signals,
and option -p lists all signals currently trapped.
Signals: Write a script that uses a temporary file (really, much better to avoid
temporary files altogether), and uses trap to clean it after the script exits,
or even when the script is interrupted before finishing!
Common pitfalls is basically everything above. Let’s try to hit as many as possible.
Good luck! :)