Dup Ver Goto 📝

BashSh

PT2/aw/os/shell does not exist
To
244 lines, 1168 words, 7512 chars Page 'BashSh' does not exist.

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
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