Bash-Fu
I use the terminal to navigate and perform actions as much as I can, as I find I can work much more quickly. However, I'm always learning new shortcuts that make my life much easier.
This post assumes you're running your bash prompt in emacs mode. If you're not sure, then it's probably in emacs mode, as it's the default
Recall and Substitution Commands
Probably my most commonly used shortcut is the !! command. It executes the last command typed. This is particularly useful on Ubuntu, e.g.
$ apt-get install cowsay E: Could not open lock file /var/lib/dpkg/lock - open (13 Permission denied) E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
I missed out sudo, which is needed to install.
$ sudo !! sudo apt-get install cowsay [sudo] password for michael:
By using the !! command, it places the previous command after sudo, which executes the command.
You can use a similar command to access any previous commands in your bash history. It is !-n, where n is the number of lines to go back. This means that !! and !-1 are equivalent, and !-2 means the command you executed before the most recently executed one.
Finally, there's a third substitution shortcut that's rarely known. Imagine this situation:
$ ps -u micheal | grep firefox ERROR: User name does not exist.
I have a rogue Firefox instance that I need to kill. However, I accidentally typo'd my username, and there's a few ways I could fix it. I could press the up arrow, then navigate to that point in the line and fix it. Or, I could use substitution.
$ ^ea^ae ps -u michael | grep firefox 1134 ? 03:55:11 firefox
Those are the three commands I use most when navigating around my system and executing commands.
Shortcuts
There's also a few shortcuts that allow you to save time when typing commands in the first place. If you type fast, and find yourself getting two letters in the wrong order, you can press ctrl+t to swap them around.
Another shortcut which I find useful, is using lists. Imagine we have three files, mon.txt, tues.txt and weds.txt, and we want to move them into folder X. The following two commands are identical:
$ mv {mon,tues,weds}.txt X
$ mv mon.txt tues.txt weds.txt X
Finally, when on the command line, press CTRL+R to bring up your bash history prompt. Type part of the command you're looking for and press enter to execute the one that's matches, or press right to load the command for editing. This is useful for me when I have to ssh into a server, and I can only remember the first two digits of it's IP address. I simply have to hit CTRL+R and type "ssh 87" then press enter.
Aliases?
Of course, some of the above problems could be solved easily (and permanently) with aliases. For example, look at some of these example aliases for solving some of the problems presented above:
alias apt-get='sudo apt-get $1'
This solves the problem where I sometimes forget to type sudo.
alias sshDelta ='ssh 87.255.255.255'
This one makes it easy to ssh into the server (In this name, named Delta)
To get these working, make sure .bash_aliases is enabled in ~/.bashrc, then add them to .bash_aliases. You can then either close the terminal and open it again, or type source .~/.bash_aliases to read the file.
Attribution
I learnt a lot of this browsing around the internet over the last few months and idling in #geekup on Freenode. However, The Geek Stuff has a very comprehensive list of commands to help master your command line history, which refreshed my memory and taught me about the !-n syntax for accessing previous history lines.
Are there any command line tips you use frequently that want to share? Let us know in the comments
No related posts.
Ooh didn“t know about the two letter swap shortcut! ty XxX
For more advanced replacements you can supply a regular expression match and replacement.
!!:s/match/replacement/You’ve missed a few things:
![cmd] where [cmd] is the start of a recent command. This may be better described with an example:
$ apt-get install cowsayE: Could not open lock file /var/lib/dpkg/lock - open (13 Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?
$ whoami
wrboyce
$ sudo !apt
sudo apt-get install cowsay
[sudo] password for wrboyce:
Question marks can be used around if the command did not start/end with :
$ !?install?sudo apt-get install cowsay
You can use the :p modifier to only print the command, not execute it:
$ !!:psudo apt-get install cowsay
Use the :s// modifier in a similar manner to ^^ mentioned above:
$ !!:s/install cowsay/moo/sudo apt-get moo
(__)
(oo)
/------\/
/ | ||
* /\---/\
~~ ~~
...."Have you mooed today?"...
There is also a ‘&’ modifier that can be used to apply the previous substitution to the matched event:
$ echo install cowsayinstall cowsay
$ ^install cowsay^moo
echo moo
moo
$ !apt:&
apt-get moo
(__)
(oo)
/------\/
/ | ||
* /\---/\
~~ ~~
...."Have you mooed today?"...
There are word designators available so you can pull a specific word from each bit of history:
$ echo !!:2echo moo
moo
Word designators are 0-based, can take a range, and you can use $ to reference the last word:
$ echo !!:0-$echo echo moo
echo moo
You can also use * to reference 1-$:
$ echo !!:*echo echo moo
echo moo
And ^ can be used to reference ’1′ (the first argument), so !!:^-$ is equivalent to !!:*
!# can be used to represent the current typed command so far:
$ echo moo; !#echo moo; echo moo;
moo
moo
Cheers Caius, Will.
I can’t believe that I forgot the !word command, as I use it all the time when working on personal stuff. e.g.
$ scp ~/folder/* 87.255.255.255:folderThen I can move about the file system, and just use !scp to transfer the files again.
Also, the :p modifier to print the command instead of executing it is handy. To find the command that I used in the example above, I used the following command:
$ !scp:p
scp ~/folder/* 87.255.255.255:folder