Bash interpretation of quotes

Recently, I was attempting to pull a particular octet out of a list of IP addresses:

echo 192.168.0.1 | awk -F. '{ print $2 }'
168

That worked fine, but when I ran this through sh, the result changed:

sh -c "echo 192.168.0.1 | awk -F. '{ print $2 }'"
sh -c 'echo 192.168.0.1 | awk -F. "{ print $2 }"'
192.168.0.1
192.168.0.1

Thanks to a helpful post on Stackoverflow, it's clear that Bash is doing something strange inside quotes. Specifically, anything inside single quotes will be left alone, but characters inside double quotes may not maintain their literal meaning. Above, since $2 is inside double quotes in both cases, it will be interpreted as a Bash variable. Instead, we either need to escape the $ with a backslash:

sh -c 'echo 192.168.0.1 | awk -F. "{ print \$2 }"'
sh -c "echo 192.168.0.1 | awk -F. '{ print \$2 }'"
168
168

Or, we can keep everything inside single quotes. However, we can't just escape the ' with a backslash:

A single quote may not occur between single quotes, even when preceded by a backslash.

Hence, we have to:

  1. Close the single-quoted string (')
  2. Escape the single quote with a backslash (\')
  3. Re-open the single-quoted string and continue it (')
sh -c 'echo 192.168.0.1 | awk -F. '\''{ print $2 }'\'''
168

Author: keith

Created: 2017-11-05 Sun 19:38

Validate