> For the complete documentation index, see [llms.txt](https://freebsdfrau.gitbook.io/serious-shell-programming/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://freebsdfrau.gitbook.io/serious-shell-programming/basics/strings/compound-strings.md).

# 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!']
```
