Compound Strings

Most strings in Bourne shell are straight-forward. Using single-quotes causes the contents to be interpreted literally while using double-quotes allows string interpolation to occur and using no quotes adds word-splitting to the results.

Compound strings combine the features of unquoted, single-quoted, and double-quoted syntaxes to form a single string. You can seamlessly interchange styles without surrounding whitespace to construct a compound string.

For example, if you wanted to echo a sentence containing both double-quotes and single-quotes you can use a compound string:

1 #!/bin/sh
2 echo 'She asked, "Wie geht'\''s?"'
3 echo 'I answered, "C'"'est la vie.\""

The compound string on line 2 is actually the result of combining 3 separate strings. If we imagine space between these strings, we can more easily parse the compound string (working left-to-right):

String 1

String 2

String 3

Type

Single-quoted

Unquoted

Single-quoted

Contents

She asked, "Wie geht

\'

s?"

Interpolated?

No

Yes

No

Word Splitting?

No

Yes

No

Resulting String

She asked, "Wie geht

'

s?"

The compound string on line 3 is the combination of 2 separate strings:

String 1

String 2

Type

Single-quoted

Double-quoted

Contents

I answered, "C

'est la vie.\"

Interpolated?

No

Yes

Word Splitting?

No

No

Resulting String

I answered, "C

'est la vie"

The separate strings are combined without whitespace:

She asked "Wie geht's?"
I answered, "C'est la vie."

Below is a more complex example:

  1 #!/bin/sh
  2 args=
  3 args_safe=
  4 readarg()
  5 {
  6         local arg arg_safe
  7         read -p "Enter some text: " arg
  8         [ "$arg" ] || return 1
  9         arg_safe=$( echo "$arg" | awk 'gsub(/'\''/, "&\\\\&&")||1' )
 10         args="$args '$arg'"
 11         args_safe="$args_safe '$arg_safe'"
 12 }
 13 showargs()
 14 {
 15         local n=0 arg
 16         for arg in "$@"; do
 17                 n=$(( $n + 1 ))
 18                 printf "\targ%u=[%s]\n" "$n" "$arg"
 19         done    
 20 }       
 21 echo "< Press Enter to Exit >"
 22 while readarg;do :; done
 23 echo "Without using compound strings to escape:"
 24 printf "\targs=[%s]\n" "$args"
 25 eval showargs $args
 26 echo "Using compound strings to escape:"
 27 printf "\targs_safe=[%s]\n" "$args_safe"
 28 eval showargs $args_safe

In the above excerpt we not only utilize a compound string on line 9 as the only argument to awk, but we use compound strings to escape user input when we need to evaluate arguments safely.

Running the above code:

< Press Enter to Exit >
Enter some text: She said "Hello, World!"
Enter some text: He said 'Hello, World!'
Enter some text: 
Without using compound strings to escape:
    args=[ 'She said "Hello, World!"' 'He said 'Hello, World!'']
    arg1=[She said "Hello, World!"]
    arg2=[He said Hello,]
    arg3=[World!]
Using compound strings to escape:
    args_safe=[ 'She said "Hello, World!"' 'He said '\''Hello, World!'\''']
    arg1=[She said "Hello, World!"]
    arg2=[He said 'Hello, World!']

Last updated