contents
Useful keystrokes
Pressing Esc followed by a key is equivalent to holding down Alt and pressing that key. We use C-x for Ctrl-x, A-x for Alt-x.
Editing
Ctrl+K # kill to end of line
Ctrl+U # kill to start of line
Ctrl+W # kill word before
Ctrl+Y # paste last killed
Ctrl+X+E # load current command into editor
Requires VISUAL to be set to desired editor (def is emacs!??)
Or EDITOR (VISUAL takes priority)
Note that command is executed upon quit.
Alt-F, Alt-B # forward/back one word
Ctrl-R # search history
Command history
Up # previous command in history
Down # next command in history
A-< # go to start of command history
A-> # go to end of command history
C-r # search history backwards
C-s # search history forwards
C-g # abort search
Esc-p # prompt with : and go to previous command matching
Esc-n # prompt with : and go to next command matching
Searching History
Press C-r and start typing to search backwards; press Enter to execute the found command, or Esc to bring it up so that you can edit it.
Kill Ring
Pressing C-k 'kills' from the current character to the end of the line, and places the cut text into the 'kill ring'.
C-k # kill to end of line
C-u # kill to beginning of line
Esc-backspace # kill previous word
Esc-d # kill next word
Yanking
C-y # Yank last killed text
A-y # cycle through kill ring
Options
Set with shopt -s option to set, and shopt -u option to unset it.
histverify # when using !, allows editing command without immediately executing
Key Bindings
Bind with e.g.
bind '"C-t": "hello world"' # types 'hello world' when Ctrl-T pressed
bind '"C-xd": kill-word'
Binding commands
Commands like kill-word that you can bind to keystrokes.
You can use
bind -P # print out bindable commands and current key bindings
and
bind -P | grep -v "not bound" | less
to see a list of current bindings (grep removes those commands not bound).
Useful default bindings
Completion:
C-x/ # show possible file completions
C-x@ # show possible host completions
C-x~ # show possible uesrname completions
C-x$ # show possible variable name completions
C-x! # show possible command name completions
A-= or A-? # show possible completions
Redirection
ls > dirlist 2>&1 # stderr and stdout go into file ‘dirlist’
ls 2>&1 > dirlist # only stdout goes to file ‘dirlist’
Special files
/dev/stdout, /dev/stdin, /dev/stderr, /dev/fd/<int>,
/dev/tcp/host/port, /dev/udp/host/port
E.g.
Nc -l 3001 (on machine1), then
Echo hello world > /dev/tcp/machine1/3001
File Descriptors
[n]>filename # redirect file descriptor n to filename
[n]>|filename # as [n]>filename but overrides noclobber
[n]>>filename # append instead of clobber
[n]<&[m] # duplicate input file descriptor m to n
[n]>&[m] # duplicate output file descriptor m to n
[n]>&- # close file descriptor n
ffmpeg 2>& filename # ERROR: ambiguous redirect
ffmpeg >hello 2>&1 # redirects stdout, stderr to file hello
[n]<&digit- # duplicate fd digit to n, then close fd
[n]>&digit- # same but for output
n<>filename # open filename for both reading and writing
Stdout and Stderr
These are equivalent
&>filename
>&filename
>filename 2>&1
and all send both stdout and stderr to filename.
These are equivalent
&>>filename
>>filename 2>&1
Heredocs
[n]<<[-]word
...
word
Clobbering
set -o noclobber # prevents >filename overwriting
set +o noclobber # switches noclobber off
echo override noclobber >| filename # overrides noclobber
Queries
Are we being sourced
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
echo source
else
echo run
fi
History
history # list all history items
history | grep for # find history items containing 'for'
!! # execute last command*
!ls # execute last command starting with ls*
!434 # run command numbered 434 from history
!?hello? # run last command containing hello
!?hello # run last command ending with hello
sudo !! # run last command as root
!1234:s/hello/world/ # command 1234, but with hello replaced by world
- Unless shell option
histverifyis set.
Up/Down # go back/forward through history
Alt+R # revert changes made to recalled command
Ctrl+R # interactive reverse search
Ctrl+O # run command matched in search
Ctrl+G # exit search
Shell Options
shopt -s histverify # ! recalls command but does not execute
shopt -s dotglob # wildcard * matches entries beginning with .
shopt -u dotglob # switch dotglob off
shopt dotglob # show whether dotglob is on or off
shopt # list all shell options and their status
shopt -s extglob # enable extended globbing
Variables
Prompt
Set PS1 to set your prompt. Examples:
PS1='\u@\h:\w\$ '
PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
The second of the above examples uses colours, whereas the first does not.
To set colours, and other things, you use AnsiEscapeSequences. You use octal '\033' to write an escape character. For example
\033[32m
selects green for subsequent text.
When using AnsiEscapeSequences in the PS1 variable, you need to surround them with \[...\] so that bash knows to ignore those characters when computing the number of //printed// characters in the prompt. (Deliberately neglect to do this and have a play, and you will see why it is necessary.)
Variables you can use are:
\u It is used to display the current username.
\h It is used to the name of the computer name.
\H It is used to the name of the hostname.
\d It is used to display the date with weekday name, month name, and date.
\w It is used to display the full path of the current working directory.
\W It is used to display the last fragment of the current working directory.
\t It is used to display the current time in 24-hour format.
\T It is used to display the current time in 12-hour format.
\@ It is used to display the current time in 12-hour format with AM/PM.
\n It is used to add the new line.
\e It is used to add an ASCII escape character.
\v It is used to display the version of the bash.
\V It is used to display the version of the bash with patch level.
My current prompt also sets the title on xterm and other terminals (for example the tab title in Windows Terminal). I put this in a file named my_prompt and source it from my .bashrc.
BASE_PS1='\n\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\n\
set_term_title_prompt() {
PS1="\[\033];\h:\w\007\]""$BASE_PS1"
}
unset_term_title_prompt() {
PS1="$BASE_PS1"
}
set_term_title_prompt
The \[\033];\h:\w\007\] bit is what tells the terminal to set the tab title to host:pwd.
Extended globs
Examples
shopt -s extglob
echo "${@%%+(/aw/)}" # removing all trailing /'s