BASH is a swiss-army knife for unix user. For years I did not use its full power in the name of portability and POSIX compatibility. But it is no more - BASH is now everythere (as Python 3 does), so I am happy to fully commit to it. Bourne SHell Never Again.

Below you may find a few cool features which took my attention recently.

Recent Discoveries

$CDPATH

   CDPATH The  search  path for the cd command.  This is a colon-separated
          list of directories in which the shell looks for destination di‐
          rectories  specified  by  the  cd  command.   A  sample value is
          ".:~:/usr".

Here is how I setup it: I created $HOME/cdpath directory where symbolically linked all the most frequently used directories. Then I added the following entry to my .bashrc:

    CDPATH=.:~/cdpath
    set -o physical # show physical path instead default logical

Now, wherever on the filesystem I am, I do not have to type a full path of my favourite directory because they are all searched at the content of CDPATH variable, which is current dir and ~/cdpath:

jxa@ub22:0:~$ pwd
/home/jxa
jxa@ub22:0:~$ cd jekyl
/home/jxa/cdpath/jekyl
jxa@ub22:0:~/GIT/jkedra.github.io$ 

Also, by default pwd command is bash internal one and by default it presents the logical path (show symbolic links) which is visible here as /home/jxa/cdpath/jekyl. Since I prefer to see the physical full path instead, I may use /usr/bin/pwd which has opposite defaults or - luckily - there is a way to change bash standar behaviour with set -o physical:

pwd [-LP]
      Print  the  absolute  pathname of the current working directory.
      The pathname printed contains no symbolic links if the -P option
      is supplied or the -o physical option to the set builtin command
      is enabled.  If the -L option is used, the pathname printed  may
      contain  symbolic links.  The return status is 0 unless an error
      occurs while reading the name of the current directory or an in‐
      valid option is supplied.

Return Value

I found it useful to have an immediate feedback about the recent command status in the prompt as seen in Visual Studio Code:

prompt-vc <>

I could not to present it as nicely as VSC does but was able to squeeze the return status in the textual way, which is even more informative. See for the ?: which has been added in the both PS1 variables:

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:$?:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:$?:\w\$ '
fi

And here is the result:

jxa@ub22:0:~$ false
jxa@ub22:1:~$ sss
Command 'sss' not found, but there are 17 similar ones.
jxa@ub22:127:~$ 

In a different way than VSC does, the last status is set in the next prompt.


Readline

M is Meta which in Ubuntu usually means Alt.
C is Ctrl, in Ubuntu maps to Control key.


Moving Commands

M-f Move forward a word.
M-b Move backward a word.


Killing Commands

Killed/yanked/cut-and-pasted content is saved in a kill-ring.

C-k Kill the text from the cursor to the end of line.
M-d Kill the text from the cursor to the end of word.
M-DEL Kill the text from the cursor to the start of the word. I do not see it working at Ubuntu.
C-w Kill the text from the cursor to the previous whitespace.

C-y Yank the most recently killed text back into the buffer at the cursor.
M-y Rotate the kill-ring and yank the new top. You can do it only after C-y or M-y


Other Commands

Readline key bindings can be printed in bash using bind -P.

Bindable Readline Commands

edit-and-execute-command (C-x+C-e) - invokes an editor and executes the typed-in command.


Literature

  1. Advanced Bash Scripting Guide
  2. BashGuide
  3. Defensive BASH Programming
  4. GNU.og:
  5. Exercism Useful Bash resources
  6. GetOpts Tutorial