Bash Magic

Posted on Fri 02 December 2016 in dev

Over the years I have learned many tips and tricks when working with Bash. Some are well known while others are not. Here are a few tricks that I find the most useful.

Searching history

So you know you just typed that command but cannot remember what it was. Fine, just type <ctrl>-R. Your prompt will then look something like this:

(reverse-i-search)`':

Start typing part of your command and bash will find it for you. Search results will be narrowed down as you keep typing. Cycle forward through search results by hitting <ctrl>-R multiple times.

Cycling backwards through history with <ctrl>-S requires enabling XON/XOFF flow control with the following command:

stty -ixon

Otherwise your terminal will freeze upon hitting <ctrl>-S. Use <ctrl>-Q to unfreeze.

Press Enter to execute the search result and use the arrows to edit the command before executing.

Customizing the prompt

The prompt is defined by the PS1 variable. The default prompt is quite succinct:

PS1='\s-\v\$'

The result looks like this:

bash-4.3$

It can be improved by displaying useful information such as the date, hostname, username, current working directory and much more. Here is the PS1 I've been using these days:

PS1='┌─[\e[0;32m\t\e[0m]─[\e[0;36m\u\e[0m\e[0m \e[0;33m\w\e[0m]\n└─>\$ '

It looks like that:

┌─[13:33:37]─[john ~/git/foo/bar/www]
└─>$

See the Bash manual for more details about Bash variables.

Moving and Erasing

Hit <ctrl>-A to move the caret to the beginning of the line. <ctrl>-E will move to the end of the line.

Use <alt>-F to move one word forward and <alt>-B to move one word backwards.

<ctrl>-U will delete everything to the left of the caret while <ctrl>-K will delete everything under and to the right of the caret.

Type <ctrl>-W to delete the word to the left (until the first space character). Use <alt>-Backspace to delete the word to the left until the next special character. This is useful when working with paths and you want to delete until the next / to the left.

Recalling history

Recall the last argument of the last command with <alt>-_ (<alt>-underscore).

Run the previous command with sudo in front:

sudo !!

Expansion

Create a backup copy of a file without typing the file path twice:

cp /path/to/file{,.bak}

Configuring history

Increase the number of commands stored in the history and save the time and date each command was executed on:

HISTSIZE=100000
HISTFILESIZE=20000
HISTTIMEFORMAT="[%F %T %Z (%z)] "

The history is stored in ~/.bash_history and can be displayed with the history command.

Copy and paste

Paste the contents of the clipboard with <shift>-Insert.

Run a command with the last argument from your clipboard:

# define a function xc()
xc() {
        [email protected] "$(xclip -o)"
}

# use with
xc my_command # will execute: my_command <clipboard_contents>

How is this more useful than pasting the clipboard contents with <shift>-Insert you say? This will save you enclosing the clipboard contents with quotes since the clipboard contents are passed as a single argument to my_command.

Useful aliases

Package management:

alias i='sudo -E pacman -S'
alias r='sudo -E pacman -Rs'
alias s='pacman -Ss'
alias syu='sudo -E pacman -Syu'

Listing files and grepping:

alias ls='ls --color=auto --group-directories-first -lh'
alias lsgrep='ls | grep -i'

Systemd:

alias sc='sudo -E systemctl'

Systemd will be the topic of another post. Enjoy!