Linux administration

Advanced Shell Usage

Nguyen Hai Chau
Vietnam National University

More About Quoting

  • The shell actually has three different quoting mechanisms:
    • Single quotes
    • Backslashes
    • Double quotes

Quoting: Single Quotes

  • Putting single quotes round something protects it from special interpretation by the shell:
$ xmms 'Tom Lehrer - Poisoning Pigeons in the Park.mp3'
$ rm 'b*lls and whistles'
  • But single quotes (obviously) don't protect single quotes themselves
    • So you can't quote something like She said, "Don't go." with only single quotes

Quoting: Backslashes

  • You can put a backslash \ in front of any single character to turn off its special meaning:
$ echo M\&S
$ xmms Suzanne\ Vega\ -\ Tom\'s\ Diner.mp3
$ mail -s C:\\MSDOS.SYS windows-user@example.com

Quoting: Double Quotes

  • Putting double quotes round something protects most things within it from interpretation by the shell
    • A dollar sign $ retains its special interpretation
    • As do backticks
    • ! can't be escaped in double quotes
  • A backslash can be used within double quotes to selectively disable the special interpretation of $, ' and \:
$ mail -s "C:\\MSDOS.SYS" windows-user@example.com
$ echo "It cost $price US\$"
  • Putting a backslash in front of anything else gives you both characters:
$ echo "\*/"
\*/

Quoting: Combining Quoting Mechanisms

  • You can build up an argument for a command by combining several chunks of differently-quoted text

  • Just put the chunks next to each other with no intervening whitespace:

$ echo "double-quoted"'.single-quoted.'unquoted
double-quoted.single-quoted.unquoted
$ echo 'She said, "Don'\''t go."'
She said, "Don't go."
  • Rarely needed - the last example is probably better written as:
$ echo "She said, \"Don't go.\""

Recap: Specifying Files with Wildcards

  • * in a glob pattern can stand for any sequence of characters:
$ ls -l *.txt
-rw-rw-r-1 fred users   108 Nov 16 13:06 report.txt
-rw-rw-r-1 fred users   345 Jan 18 08:56 notes.txt
  • * on its own expands to all files in the current directory
  • Glob expansion is done by the shell
    • So a program can't tell when the user ran it with a glob as an argument

Globbing Files Within Directories

  • You can use globs to get filenames within directories:
$ ls Accounts/199*.txt
Accounts/1997.txt Accounts/1998.txt Accounts/1999.txt
$ ls ../images/*.gif
../images/logo.gif ../images/emblem.gif
  • You can also use globs to expand names of intervening directories:
$ cd /usr/man && ls man?/lp*

man1/lpq.1.gz   man1/lprm.1.gz      man4/lp.4.gz    man8/lpc.8.gz
man1/lpr.1.gz   man1/lptest.1.gz    man8/lpd.8.gz

Globbing to Match a Single Character

  • * matches any sequence of characters
  • To match any single character, use ?:
$ ls ?ouse.txt

Matches mouse.txt and house.txt, but not grouse.txt

  • Can be useful for making sure that you only match files of at least a certain length:
$ rm ???*.txt

Matches any file ending in .txt that has at least three characters before the dot

Globbing to Match Certain Characters

  • Instead of matching any single character, we can arrange to match any of a given group of characters

  • *.[ch] matches any file ending in .c or .h

  • *[0-9].txt matches any text file with a digit before the dot

  • You can use a caret as the first thing in the brackets to match any character that isn't one of the listed ones

  • [ˆa-z]*.jpg matches any JPEG file that doesn't begin with a lower-case letter

  • To match any hidden file except the . and .. directories: .[ˆ.]*

Generating Filenames: {}

  • You can use braces {} to generate filenames:
$ mkdir -p Accounts/200{1,2}
$ mkdir Accounts/200{1,2}/{0{1,2,3,4,5,6,7,8,9},1{0,1,2}}
  • You could even combine those two lines:
$ mkdir -p Accounts/200{1,2}/{0{1,2,3,4,5,6,7,8,9},1{0,1,2}}
  • Or combine brace expansion with quoting:
$ echo 'Hello '{world,Mum}\!
Hello world! Hello Mum!
  • Braces can be used for generating any strings, not just filenames
  • Distinctly different from ordinary glob expansion — the words generated don't need to be names of existing files or directories

Shell Programming

  • The shell is designed to be both:
    • A convenient environment to type commands into
    • A simple programming language
  • Any command that can be typed at the command line can be put into a file — and vice versa
  • Programming features include variables, loops (including for), and even shell functions
  • The Unix component approach makes it very easy to write shell scripts to perform fairly complex tasks

  • Common application domains for shell scripting include:

    • Text processing
    • Automation of system administration tasks

Exercise

  • a. Print out the following message: *** SALE $$$ ***.
  • b. Try escaping the same string using single quotes, double quotes and backslashes.
  • c. Echo the message 'quoting isn't simple', escaping the spaces by putting single quotes around it.
  • d. Use the glob pattern .[ˆ.]* to list all the hidden files in your home directory.
  • e. To find out what shells are available on your system, list the programs in /bin whose names end in sh.
  • f. Use [] brackets to list all the files in /usr/bin with names starting with a, b or c.