Bash Tricks

Bash history

Bash will remember all command you enter so it is possible to repeat them without retyping. See also Bash Event Designators

With arrow up or arrow you can cycle through all the commands.

List all commands entered so far

2024 ls /tmp
2025 date
2026 grep error /var/log/syslog

You can use those numbers to directly repeat such a command with. E.g. this will repeat the date command in my example

You can also use -x to refere to the command x before us. E.g. -1 is the last command, -2 the one before that ...

This will repeat the very last command in the list (in this case the grep command)

Warning the command is executed immediately, so no need to press return.

Repeat last command that started with gi

Something very similar is CTRL+r to search for previous command. For example type this to also search for the last command starting with gi

CTRL r gi

You can press CTRL + r again to search for even older commands on your history that also start like this or continue typing to restrict the search to more exact hits. Maybe while search backwards you reconsinder and want to back to younger hits. No problem, with CTRL + s you can search in the other way again. Only drawback is, that CTRL + s may be bound to another function. You may try this to get it back working

stty -ixon

Add it to your .bashrc to have it always working.

Very often you need to reuse parameters of previous commands. For example, you copy one file to another and want to modify the new file. Normally you would do

cp template.txt newlist.txt
vi newlist.txt

Instead of re typing the last parameter you can use !$ to use the last word of the previous command

cp template.txt newlist.txt
vi !$
# vi newlist.txt

If you need not only the last parameter but all parameters

vi a.txt b.txt c.txt
tar -cf backup.tar !*
# tar -cf backup.tar a.txt b.txt c.txt

You may want to repeat a command but change something in it. Just type ^old^replacement to achieve this. For example if you tried to edit files with vi but want to use emacs instead

vi a.txt b.txt c.txt
# emacs a.txt b.txt c.txt

Command line help

You will need to repeat parameters very often, e.g. when you create copies. Some examples of this:

cp document_old.txt document_new.txt
cp document.txt     document_Backup.txt

With the {first,second} syntax you can have that much shorter

cp document_{old,new}.txt
cp document{,_Backup}.txt
Ctrl+Amove to the start of the line
Ctrl+Emove to the end of the line
Ctrl+UCut from the cursor to the beginning of the line into the clipboard
Ctrl+KCut from the cursor to the end of the line into the clipboard
Ctrl+WCut from the cursor to the start of the word into the clipboard
Ctrl+Ypastes text from the clipboard

Bash configuration

export HISTSIZE=1000Remember the last 1000 commands in memory for one session
export HISTFILESIZE=2000Persist the last 2000 commands on disk to load it next time
export HISTCONTROL=ignorebothDon't store commands which start with a space or successive identical entered commands
shopt -s histappendThe last Bash session you close won't overwrite the history
shopt -s histverifyCommands you repeat with ! are not executed immediately

Jump to recently visited directories

Push a new directory to the stack and change to that directory

# pwd

# pushd /etc/network/

# pushd /var/log/
/var/log /etc/network /tmp

# pushd /usr/sbin/
/usr/sbin /var/log /etc/network /tmp

# dirs
/usr/sbin /var/log /etc/network /tmp

A simple pushd swaps the topmost directory on the stack with the next one and changes the current directory to the new topmost one. Very handy to jump between two directories.

# pushd
/var/log /usr/sbin /etc/network /tmp

# pwd

# pushd
/usr/sbin /var/log /etc/network /tmp

# pwd

With +x or -x you can select the x. directory (count starts with zero) counted from the left or the right side to be the new topmost directory.

# pushd +2
/etc/network /tmp /usr/sbin /var/log

/# pwd

With popd the topmost directory is removed from the stack and the current directory will be set to the new topmost directory. With -n the current directory is not changed.

# dirs
/etc/network /usr/sbin /var/log

# popd
/usr/sbin /var/log

# pwd

# popd

# pwd

With +x and -x you can again remove the x. directory counted from left or from right. If you remove the topmost directory (+0) the current directory is change to the new topmost directory.

You can also get the last directory you were before the current directory with the following variable

echo "$OLDPWD"

Command Substitution

Repeat last token of the last command

# echo /etc/group /etc/passwd >/dev/null
# echo !$
echo /dev/null


you get the last token at the current cursor position.

Repeat the last argument of the last command

# cp backup2008a.tar /mnt/streamer/backup2008a.tar 2>/dev/null
# echo $_

Repeat the last command with a substitution

# cp backup2008.tar /mnt/streamer/
# ^2008^2009^
cp backup2009.tar /mnt/streamer/

However, this substitutes only the first occurrence, which also applies to the long version

# cp backup2008a.tar backup2008b.tar /mnt/streamer/
# !!:s/2008/2009/
cp backup2009a.tar backup2008b.tar /mnt/streamer/

The long version can also substitute all occurrences

# cp -v backup2008a.tar backup2008b.tar /mnt/streamer/
# !!:gs/2008/2009/

Turn Beep Off (e.g. while autocomplete)

xterm: xset b off
setterm -blength
echo 'set bell-style visible' >> ~/.inputrc