.. highlight:: console .. role:: bash(code) :language: bash :class: highlight Completion, wildcards and expansions ------------------------------------ Before we look at :dfn:`tab completion` and :dfn:`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. :command:`touch` creates empty files, or updates the timestamp on existing files. Now try:: $ echo foo* The shell :dfn:`expands` :kbd:`*` to produce a list of any files in the current directory whose names start with :file:`foo`, followed by any number of characters. This expansion is done by the shell *before* the arguments are passed to the program. From :command:`echo`'s point of view, the above line is equivalent to:: $ echo foo foo1 foo2 foo3 What happens if you type :kbd:`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 :kbd:`?` character matches one single character. This meaning of the :kbd:`*` and :kbd:`?` :dfn:`wildcards` is known as :dfn:`glob expansion`. "Globbing" is a simple version of much more powerful :dfn:`regular expressions`. Try typing:: $ ls $ ls -l foo1 $ ls # -l foo1 What does the :kbd:`#` do? This is useful when writing :dfn:`shell scripts`. Now try:: $ echo foo#bar Can you work out why the :kbd:`#` doesn't seem to work here? Let's try another kind of expansion: :dfn:`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 :command:`echo`:: $ echo mv fo{,o4} $ echo mv bar{1,9}0 Remember why that works? Now let's clean up a bit:: $ rm foo* .. warning: You should always be careful when using :command:`rm`, especially when using the :option:`-r` and :option:`-f` options. The shell is powerful, but if you're not careful it will happily delete all your files. 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 :kbd:`"I'm not possible!"` with all its quotes? Actually, you *can* type double quotes inside double quotes, using a backslash :dfn:`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?