Tuesday, 7 July 2009

5 Bash Tips, Part II

This article is a continuation to my other Bash-related post, 6 Bash Productivity Tips. Since that article gathered many useful comments and I bumped into several more over the net, here are 5 more tips and tricks. Although these may not be necessarily productivity-related, they will surely ease working in a Bash terminal and it may be worth knowing them. If you're not familiar with the terminal, command-line interface and Bash you can go ahead and read my introduction to Linux CLI.

Using Ctrl+R (reversed search)
Ctrl+R performs a reversed search in the history. For example, typing the command df -h | grep /dev/sda1, then pressing Ctrl+R and typing only df, the most recent command will be auto-completed and performed upon pressing Enter. Ctrl+R searches for occurences of what you type and returns the last command in which it finds it:

$ df -h | grep /dev/sda1
/dev/sda1 83G 65G 14G 83% /
(reverse-i-search)`df': df -h | grep /dev/sda1

Where COMMAND is any command executed in the past or the beginning of a command. This calls the most recent command starting with COMMAND. For example:

$ for i in *.ogg; do vorbiscomment -l $i; done
$ ls
$ !for
for i in *.ogg; do vorbiscomment -l $i; done

In the above example, using !for followed by Enter executed the last occurence in the history which started with for.

Exit status: echo "$?"
This will return the exit status of the last executed command. It can prove useful in scripts. A command returns 0 if it ended successfully and a non-zero value otherwise:

$ cat /etc/motd | head -1
Linux debian 2.6.26-2-686 #1 SMP Sun Jun 21 04:57:38 UTC 2009 i686
$ echo "$?"
$ cat /etc/mots
cat: /etc/mots: No such file or directory
$ echo "$?"

Using !! with sudo
Here's a useful example of !! from one of the comments in the older post. !! will replace the last command, so using sudo !! will execute the last command preceding it with sudo. Very useful when performing commands which need root privileges and forgetting to precede them with sudo. Example:

$ apt-get update
E: Could not open lock file /var/lib/apt/lists/lock - open (13 Permission denied)
E: Unable to lock the list directory
$ sudo !!
sudo apt-get update

Run a specified command in history with !NUMBER
This will run command numbered NUMBER from history. Examples: !250, !1, etc. To view the history and the corresponding numbers, type history:

$ history | tail -3
534 for i in *.ogg; do vorbiscomment -l $i; done
535 history
536 history | tail -3
$ !534
for i in *.ogg; do vorbiscomment -l $i; done
Error opening input file '*.ogg'.

In the above example, command number 534 was executed when typing !534.

For other suggestions or corrections to these tips, please use the comments below.


Anonymous said...

There's no need to use quotes when checking exit status, `echo $?` works just as well. Ofcourse if you were attached to using quotes you could always start typing "!!" also...


Anonymous said...

apt-get is not a bash command.

Ian MacGregor said...

Thanks for this post. I really liked "Run a specified command in history with !NUMBER" and didn't know about it until now.