Example Grave Accent Quoting & Escaping Example Quoting Parameter Substitution

Command Substitution

Next up is COMMAND SUBSTITUTION although there is a lot about quoting is this section too. It is far too difficult to split quoting away altogether, so instead I have elected to combine both sections and include all the QUOTING information here too where appropriate.

The Grave Accent (`)

We have already seen the set of back-quotes (or grave accents) in use in Script Example 1.1 and Example For Syntax where the count variable was incremented. The shell reads the command, or list of commands, or pipeline from between the grave accents and executes them. The output from this operation is then available to the shell for use in setting a variable or echoing to the terminal. When the command string is executed in this way, the output is stripped of newlines and blanks are truncated to one space between words (unless preserved in double-quotes). The grave accent example below shows several different uses of the grave accent of varying complexity.

Example grave accent

currentDir=`pwd`
lineCount=`wc -l $fileName | cut -c1-8`
thirdPath=`echo $PATH | cut -f3-3 -d:`
lastWord=`head -$lineCount $fileName | tail -1 | tr '''/' | basename`

In order, these commands and pipelines are all used to set some variable values.

  • First is getting the current directory using the pwd command, the simplest usage. Just execute the command and use the output to set the variable.
  • Next is getting the count of lines in a file. Use the wc command (word count) with the -l flag (lines) then pipe this to the cut command and use the -c flag (characters) to cut out the 1st to 8th character (the number) from the output. Use this to set the variable. The cut is required because wc insists on including the filename in the output string. Also beware of the number part, as it is not an integer but a string of numbers. If you want a number, then use the expr command to add a zero to the result which has the effect of converting the type. Although I said earlier that shell variables are un-typed, the test command gets upset when presented with a string and is then told to evaluate it as greater or less-than another number. The variables maybe typeless, however their contents are typed unless converted.
  • Next is getting the third string from a complex string list. The PATH environment variable (See - Startup & Environment) is a list of search paths for the UNIX system to use when searching for command locations within the directory structure. Each path is separated from its neighbour by a colon thus: [/bin:/usr/bin:/usr/lib:/usr/etc]. This command pipeline echoes the path string into cut using the -f flag (field) to select the third field. The -d flag specifies the delimiter character for the fields as a colon in this case. Once again the result of the executed pipeline is used to set a variable.
  • Lastly finding the last word on a particular line. Use the head command with the line_count variable to echo out the top line_count lines of a file. Pipe this through the tail command and only pass the last one line. Having got the line you want, pipe this through tr (transform) and change each blank into a forward-slash (a UNIX directory separator). Then pipe this through basename which always strips away the full path leaving just the filename. This leaves you with just the last word, however long the line was, and however many words there were on the line, which can then be used to set our variable.

Quoting and Escaping

The difference between the single and double quote are also useful to know. The single quote is what you use to enclose a literal string. Whatever is between single quotes remains unchanged by the shell. If you enclose something in double quotes then concatenated blanks are preserved (as in the literal case with the single quotes) but variables are substituted by their values and filenames are expanded from their wild-cards to full filenames and or paths. The best way to see this is in the example below.

Example quoting

my_name="Fred Smith"		# Set a variable
echo "$my_name"			# Will output - Fred Smith
echo '$my_name'			# Will output - $my_name

This may give the impression that the single quote is not much use. However, if you want to echo a dollar sign out to another script file for later execution, it can be very handy. See below.

echo "echo \"'$my_name'\"" > $file_name

Here the echo statement is creating another echo statement in an output file for later use. The $my_name variable is hidden inside the single-quotes and so will be passed as a literal string to the output file. Another feature shown here is the back-slash which is used as an escape signal for the shell. It tells the shell not to read the next character, but just pass it on. In this way the double-quote also makes it to the output file unscathed. The backslash can be used to escape any character that is special to the shell - even a newline. This allows you to create very long lines (See - Functions). To pass a back-slash use a double back-slash.

Parameter Substitution:

As noted earlier, the key character here is the dollar symbol ($) which instructs the shell to substitute the value where the parameter name (or variable) is located. There is a touch more flexibility here than at first appears however. There are in fact 5 different ways that the shell can substitute the value depending on the syntax used.

  1. ${name} The value, if any, is substituted. The braces are only required if name is followed by characters which are not to be interpreted as part of the name string. For instance, you might always use a temporary file name which is generated from the running script using the form "${0}.tmp" which creates a file name of "script.tmp".
  2. ${name:-word} The value, if any, is substituted. If the value is NULL, substitute word instead. Word can be a literal string, another parameter or a substituted command string output. Can be used to substitute a positional parameter ($digit).
  3. ${name:=word} As above but cannot be used to substitute a positional parameter.
  4. ${name:?word} If name is set and is not NULL, substitute its value. Else output word and exit from shell. If word is missing, the message 'parameter null or not set' is output. This can be a useful debugging aid.
  5. ${name+word} If name is set and is not NULL, substitute word. Else substitute nothing. This means the parameter is always substituted by word unless parameter is null, in which case it remains null.
Home Next Preface Introduction Basic Shells Shell Syntax Built-In Commands Command Substitution Startup & Environment Pipes, Lists & Redirection Input & Output Using Files Design Considerations Functions Debugging Putting It All Together Appendix Code Examples
Page 206
This page was brought to you by rhreepe@injunea.demon.co.uk