title | author | date | lang |
---|---|---|---|
Working with bash — shell internals |
CSC Training |
2019-12 |
en |
- At its base, a shell is simply a macro processor that executes commands.
- A Unix shell is both a command interpreter and a programming language.
- As a command interpreter, the shell provides the user interface to the rich set of utilities.
- The programming language features allow these utilities to be combined.
- Shells may be used interactively or non-interactively. In interactive mode, they accept input typed from the keyboard. When executing non-interactively, shells execute commands read from a file.
- There are a multitude of different shells available.
- Bourne Again shell — bash — is probably dominant.
- When the shell reads input, it proceeds through a sequence of operations. Roughly speaking, the shell:
- reads input and divides it into words and operators; then
- parses these tokens into commands and other constructs, removes the special meaning of certain words or characters, expands others, redirects input and output as needed; and finally
- executes the specified command, waits for the command’s exit status, and makes that exit status available for further inspection or processing.
- A command is just a sequence of words; the first word generally specifies a command to be executed, with the rest of the words being that command’s arguments.
- Readline is the library that handles reading input when using an interactive shell.
- By default, the line editing commands are similar to those of emacs. A vi-style editing interface is also available.
- Readline can be configured to taste with
~/.inputrc
file.
- Move to the start/end of the line:
C-a
/C-e
. - Move a word forward/backward:
M-f
/M-b
. - Kill rest of the line:
C-k
.- Killed text is copied into yank buffer and can be inserted back with
C-y
.
- Killed text is copied into yank buffer and can be inserted back with
- To clear the screen while retaining the current line, type
C-l
.
- When executing interactively, bash displays the primary prompt
PS1
when it is ready to read a command, and the secondary promptPS2
when it needs more input to complete a command.- Bash allows these prompt strings to be customized by inserting a number of backslash-escaped special characters:
$ PS1="(\!) \h:\W\$ "
\! = history number of this command
\h = hostname up to the first .
\W = the basename of current working directory
\$ = if effective UID is 0, a #
, otherwise a $
- Pressing the
TAB
key attempts to perform completion on the text before cursor. - Bash attempts completion treating the text as:
- a variable (if the text begins with
$
), - username (if the text begins with
~
), - hostname (if the text begins with
@
), or - a command (including aliases and functions) from
$PATH
. - If none of these produces a match, filename completion is attempted.
- a variable (if the text begins with
- To just see possible completions hit
M-?
and to insert all possible completions hitM-*
.
- The shell provides access to the command history, the list of commands previously typed. The value of
HISTSIZE
variable is used as the number of commands to save in a history list.- On startup, the history is initialized from the file named by the variable
HISTFILE
, and when shell exits the last$HISTSIZE
lines are saved to that file.
- On startup, the history is initialized from the file named by the variable
- To access the history you use
UP
andDOWN
keys. - You can also search the history by pressing
C-r
. - To view the complete history, use
history
command.
- History expansions introduce words from the history list, making it easy to repeat commands, or fix errors in previous commands quickly.
!n
refer to command line n.!-n
refer to the current command line minus n.!!
refer to previous command.!string
refer to the most recent command starting with string.!?string?
refer to the most recent command containing string.^string1^string2^
Repeat the last command, replacing string1 with string2.
$ for i in *; do echi $i; done
$ ^echi^echo^
- Quoting is used to remove the special meaning of certain characters or words to the shell.
- There are three quoting mechanisms: the escape character
\
, single quotes''
, and double quotes""
.- The escape character preserves the literal value of the next character.
- Single quotes preserve the literal value of each character within the quotes.
- Double quotes preserve the literal value of each character within the quotes, with the exception of
$
,`
, and\
.
$ echo \$HOME
$ echo '$HOME'
$ echo "I'm \$HOME"
- When a command is executed, the shell performs the following actions, from left to right:
- Variable assignments and redirections are stripped away and saved for later processing.
- Any words left are expanded. If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments.
- Redirections are performed.
- Variable assignments undergo expansions and quote removal.
- Command is executed.
$ LANG=fi_FI.utf8 ls -ld ~/*
- Expansion is a process of exchanging a word with one (or more) another word, with certain rules.
- There are seven kinds of expansions, performed in the following order:
- Brace expansion
- Tilde expansion
- Parameter and variable expansion
- Arithmetic expansion
- Command substitution
- Word splitting
- Pathname expansion
- Brace expansion is a mechanism by which arbitrary strings may be generated. It is of form
[preamble]{str[,str,…]}[postscript]
.
$ mkdir -p exp/{jan,feb,mar,apr}/run{1..3}
- Brace expansions may be nested.
$ touch exp/{{jan,mar},feb/run{1,2}}/skip
- Tilde expansion (almost) always expands to (some) user's home directory
$HOME
.
$ echo ~
$ echo ~root
- Tilde expansion can also be used to refer to current working directory
$PWD
, or previous working directory$OLDPWD
.
$ cd ~/Documents
$ cd /tmp
$ echo ~
$ echo ~+
$ cd ~-
- The shell scans the command line for the characters
*
,?
, and[
. If one of these is found, the word is regarded as a pattern, and replaced with an alphabetically sorted list of file names matching the pattern.*
matches any string, including an empty string.?
matches any single character.[…]
matches any one of the enclosed characters. If the first character following the[
is!
or^
then any charater not enclosed is matched.
$ ls -d ?e*
$ ls -d *[cw]*
$ echo {/usr,}/bin/t[!r]*
bg [jobspec]
cd [dir]
echo [args]
export [name]
fg [jobspec]
history
jobs [jobspec]
kill [pid | jobspec]
pwd
unalias [name]
unset [name]
times : Show accumulated user and system times for the shell.
type [name] : Indicate how each name would be interpreted.
ulimit [limit] : Control the resources available to the shell.
umask [mode] : The user file-creating mask is set to mode.
- Signals are asynchronous notifications that are sent to processes when certain events occur.
trap
allows you to catch signals and execute code when they occur.- Option
-l
lists all available signals, and option-p
lists all signals currently trapped.
- Option
$ trap "echo kukkuu" SIGUSR1
# Run something important, no Ctrl-C allowed.
trap "" SIGINT
important_command
# Less important stuff from here on out, Ctrl-C allowed.
trap - SIGINT
not_so_important_command