Advanced shell usage
At this point I’m assuming that you already know how to use the shell to a basic level. We’re going to talk about a few tips and tricks to get better at it.
Tab completion
One of the things that seems tedious about using the shell at first is needing to type out so many long commands. The shell actually provides many ways to make this quicker. The first thing we’ll look at is tab completion. This uses the “tab” key on your keyboard. Suppose I open my terminal and I want to cd into a directory called current/emat10006web/. It’s annoying to have to type out the full folder name and there’s also a good chance I’ll make a mistake when typing but there’s an easier way. Type cd cu and then push tab. If there’s only one possible file or directory name beginning with cu then it will complete to cd current i.e.
$ cd cu <tab>
$ cd current/
Note that I haven’t pushed the enter key yet as I’m still typing this command so I’m not ready to run it yet. Now if emat10006web is the only file or directory in current I can simply push tab again to get:
$ cd current/ <tab>
$ cd current/emat10006web
As it happens there are several files in current and they don’t all start wit the same letter so instead I see
$ cd current/ <tab><tab>
emat10006/ emat10006web/ primevenv/ tmp/
Note that the first time I push the tab key nothing happens. This is because it’s ambiguous what filename should be used to complete the command. The second time I push tab the shell shows me a list of possible completions. I want one of the ones that begins with “e” so I’ll type that and push tab again
$ cd current/e <tab>
$ cd current/emat10006
Now because there were two possibilities beginning with “e” and each begins with “emat10006” it has completed that much for me. To get the full “emat10006web” I’ll need to add a “w” and push tab again
$ cd current/emat10006w <tab>
$ cd current/emat10006web/
At this point I’ve completed the command and can push enter to run it. The description above may sound overly complicated but if you get used to using tab completion it will start to seem natural: you just have to try it.
Rerunning commands
Something else that helps is being able to locate previously run commands with the arrow keys. After running some commands in the shell see what happens when you push the up and down arrow keys. The shell allows you to navigate through all of the previously typed commands. You can find a previous command and either run it as it is or edit the command and run it. This is particularly useful if you make a mistake while typing a long command: just push “up” and then fix the mistake and push enter again. You can see a list of all previously typed commands by running the history command e.g.:
$ history
...
1986 mv sum.c array.c
1987 make
1988 vim Makefile
1989 touch array.c
1990 make
1991 ./array.exe
1992 touch array.c
1993 cat $!
1994 touch array.c
1995 cat array.c
1996 make
1997 ./array.exe
1998 PS1='$ '
1999 cd current/
2000 cd ..
2001 history
To see only those commands containing the string “gcc” you can filter the output using grep like so
$ history | grep gcc
1707 gcc -Wall -std=c99 argcount.c -o argcount.exe
1713 gcc -Wall -std=c99 getinput.c -o getinput.exe
1716 gcc -Wall -std=c99 getinput.c -o getinput.exe
1723 gcc -Wall -std=c99 getinput.c -o getinput.exe
1727 gcc -Wall -std=c99 getinput.c -o getinput.exe
1731 gcc -std=c99 -Wall outerr.c -o outerr.exe
1737 gcc -std=c99 -Wall retcode.c -o retcode.exe
1817 gcc conditional.c
1819 gcc conditional.c
2002 history | grep gcc
The numbers next to each command in the history output can be used to repeat any command. To repeat command 1817 simply type !1817 and hit enter:
$ !1817
gcc conditional.c
gcc: error: conditional.c: No such file or directory
gcc: fatal error: no input files
compilation terminated.
The previously typed command can always be referred to as !!. This is useful if you want to rerun that command but with an extra string before or after it. For example on Linux or OSX many administrative tasks need to be run with sudo. If you forget to put sudo at the beginning of a command you can then repeat it with sudo by typing sudo !!:
$ apt-get install gcc
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?
$ sudo !!
sudo apt-get install gcc
[sudo] password for oscar:
Reading package lists... Done
...
You can also refer to the last word of the previously typed command as !$. This is useful when you want to run several commands on e.g. the same filename. A common example is to create a directory and then cd into it:
$ mkdir some_long_directory_name
$ cd !$
cd some_long_directory_name
There is also a way to search for a command and run it using Ctrl-R. Push the control key and then the R key. Now type some part of a previously typed command and it will suggest a command line to run. If the command line is correct you can simply push enter to run it. Try it!
Another good way to reduce typing out long commands is to save those commands into files. This is covered in the next section about Makefiles.
Next section: makefiles