Background
- Based on Bourne shell
- Introduced readline library
- Unlike busybox, bash doesn't include work-alike commands for common utilities like tar and rm.
Start-up with bash --login
- If it exists, /etc/profile is first sourced; use strace bash --login to watch; typical contents for this are something like:
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
if [ "$PS1" ]; then
if [ "$BASH" ] && [ "$BASH" != "/bin/sh" ]; then
# The file bash.bashrc already sets the default PS1.
....
# The default umask is now handled by pam_umask.
# See pam_umask(8) and /etc/login.defs.
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
Start-up with bash --login
- After that, typically /etc/bash.bashrc is consulted
- Then /etc/bash_completion is consulted for completion information
- It's hard to believe, but working over the command line completion code is typically the most time-consuming part of the bash start-up.
Start-up with bash --login personalization
- Next comes the personalization code. First ~/.bash_profile is checked
- Then ~/.bash_login
- Then ~/.profile
When you exit
- The file ~/.bash_logout is first consulted
- Then /etc/bash.bash_logout
Start-up of just bash
- First /etc/bash.bashrc is consulted
- Then gobs of completion data are worked through
- Then ~/.bashrc
source, src, or just "dot"
- Most shells support the ability to read more code into the current shell process, much like an "#include" in C
- This is a separate and different ability from executing a child bash process.
source, src, or just "dot"
- The advantage of doing this is that this read-in code can change the current process's state; a separate child process cannot do so
Scripting
- Bash scripts need two attributes to be standalone:
- Permission bits must include "x"
- The first line of the file needs to be formed like "#!/bin/bash", or perhaps even "#!/usr/bin/env bash"
Short-circuits
- The && and || commands allow for short-circuiting
- With &&, if the first command fails, then the second one is not executed
- With ||, if the first command succeeds, then the second is not executed
Subshells
- You can create a subshell with ( ), which particularly useful for backgrounding a statement list
Job control
- fg, bg, and jobs
- bg sends jobs to the "background"
- fg brings jobs back to the "foreground"
- jobs lists all jobs associated with a shell
The directory stack
- pushd, popd, dirs
- pushd SOMEDIR → pushes the current working directory to the stack and changes the working directory to SOMEDIR
- popd → pops the top item from directory stack and changes the working directory to that directory
- dirs → show the directory stack
Variables
- To set, just use an "="; however you can also use "declare", which lets you create numeric and array variables, or declare a variable to be "read-only".
$ var1=xyz
$ declare -r var2=zyx
$ var2=xyz
bash: var2: readonly variable
$ unset var2
bash: unset: var2: cannot unset: readonly variable
Environmental variables
- These are different; these can be inherited by child processes (see environ(7)).
Removing variables
- Use "unset" to remove variables
More declarations
- "declare" by itself shows all variable state
-a declare an array variable
-i declare an integer variable
-r read-only variable
-x create an environment variable, like export
Important keyword variables
Important keyword variables
- HISTFILE
- HISTFILESIZE
- HISTSIZE
- PATH
Locales
- Useful are "locale" and "locale -c charmap":
$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
[ ... ]
LC_ALL=
Locale
$ locale -c charmap
LC_CTYPE
UTF-8
$
Accessing history with exclamation
- Most useful is probably just !! (do previous)
- Then !$ (last argument from last command)
- After, !-N (previous Nth command)
- After !N (absolute number of command)
Functions
name () {
[...]
}
shopt
- The number of Bash internal shell options (as opposed to command line arguments) has grown huge -- just look at the long listing from pp. 351-353 in the text.
- Then look at the even longer list in the current Bash.
- Best new one in my opinion is "extglob" providing the !() syntax.
Arithmetic in Bash
- In most older shells, arithmetic was done either by bc/dc or expr.
- Bash supports some arithmetic natively with the (( )) syntax.
- For a simple expression, use $(( ))
- As part of compound statement, use (( ))
- Variables don't need the $ sigil
$ echo $((3+4))
7
$ echo $((12 == 3)) # booleans also!
0
$ echo $((12 == 12))
1
Advanced exercises on page 368
- Try exercises 14 and 15. You might find referring to the Bash man pages allow a more succinct formulation for these two functions than the material presented in the chapter.