7. Completion, wildcards and expansions¶
Before we look at tab completion and shell expansions we’ll need some files to work with. Change into the working directory for this course that you made last time and type:
$ touch fo foo foo1 foo2 foo3
List the directory to see what happened. touch creates empty files, or updates the timestamp on existing files.
Now try:
$ echo foo*
The shell expands * to produce a list of any files in
the current directory whose names start with foo
, followed by
any number of characters. This expansion is done by the shell before
the arguments are passed to the program. From echo’s point
of view, the above line is equivalent to:
$ echo foo foo1 foo2 foo3
What happens if you type cat foo followed by the tab key twice?
Now try running:
$ ls -l fo*
$ touch fo?
$ ls -l fo*
From the modification times of the files, you can see that the ? character matches one single character. This meaning of the * and ? wildcards is known as glob expansion. “Globbing” is a simple version of much more powerful regular expressions.
Try typing:
$ ls
$ ls -l foo1
$ ls # -l foo1
What does the # do? This is useful when writing shell scripts. Now try:
$ echo foo#bar
Can you work out why the # doesn’t seem to work here?
Let’s try another kind of expansion: brace expansion. Run:
$ touch bar{10,20,30}
and list the files in the directory to see what happened. This can be very useful when copying or moving files with only small changes in the name:
$ mv fo{,o4}
$ mv bar{1,9}0
To better understand what the expansion is doing, try prefixing the line with echo:
$ echo mv fo{,o4}
$ echo mv bar{1,9}0
Remember why that works?
Now let’s clean up a bit:
$ rm foo*
Sometimes we don’t want expansion to happen. Double and single quote marks allow you to locally turn off bits of the shell’s syntax:
$ echo #foo
$ echo "#foo"
$ echo '#foo'
Single quotes are more restrictive than double quotes:
$ echo "hello!"
$ echo 'hello!'
What happened the first time? Can you use double quote symbols between double quotes? How about between single quotes? Can you get the terminal to echo the phrase "I'm not possible!" with all its quotes?
Actually, you can type double quotes inside double quotes, using a backslash escape character. You need escapes in any system with text delimiters where you sometimes need to show the delimiter itself. The escape character may differ, though.
- How do you print a backslash itself using double quotes?
- Using single quotes? Why does this mean you can never print out a single quote from between other single quotes, even with a backslash escape?