How to escape single quotes within single quoted strings

Let's say, you have a Bash alias like:

alias rxvt='urxvt'

which works fine.

However:

alias rxvt='urxvt -fg '#111111' -bg '#111111''

won't work, and neither will:

alias rxvt='urxvt -fg \'#111111\' -bg \'#111111\''

So how do you end up matching up opening and closing quotes inside a string once you have escaped quotes?

alias rxvt='urxvt -fg'\''#111111'\'' -bg '\''#111111'\''

seems ungainly although it would represent the same string if you're allowed to concatenate them like that.


If you really want to use single quotes in the outermost layer, remember that you can glue both kinds of quotation. Example:

 alias rxvt='urxvt -fg '"'"'#111111'"'"' -bg '"'"'#111111'"'"
 #                     ^^^^^       ^^^^^     ^^^^^       ^^^^
 #                     12345       12345     12345       1234

Explanation of how '"'"' is interpreted as just ':

  1. ' End first quotation which uses single quotes.
  2. " Start second quotation, using double-quotes.
  3. ' Quoted character.
  4. " End second quotation, using double-quotes.
  5. ' Start third quotation, using single quotes.

If you do not place any whitespaces between (1) and (2), or between (4) and (5), the shell will interpret that string as a one long word.


I always just replace each embedded single quote with the sequence: '\'' (that is: quote backslash quote quote) which closes the string, appends an escaped single quote and reopens the string.


I often whip up a "quotify" function in my Perl scripts to do this for me. The steps would be:

s/'/'\\''/g    # Handle each embedded quote
$_ = qq['$_']; # Surround result with single quotes.

This pretty much takes care of all cases.

Life gets more fun when you introduce eval into your shell-scripts. You essentially have to re-quotify everything again!

For example, create a Perl script called quotify containing the above statements:

#!/usr/bin/perl -pl
s/'/'\\''/g;
$_ = qq['$_'];

then use it to generate a correctly-quoted string:

$ quotify
urxvt -fg '#111111' -bg '#111111'

result:

'urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''

which can then be copy/pasted into the alias command:

alias rxvt='urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''

(If you need to insert the command into an eval, run the quotify again:

 $ quotify
 alias rxvt='urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''

result:

'alias rxvt='\''urxvt -fg '\''\'\'''\''#111111'\''\'\'''\'' -bg '\''\'\'''\''#111111'\''\'\'''\'''\'''

which can be copy/pasted into an eval:

eval 'alias rxvt='\''urxvt -fg '\''\'\'''\''#111111'\''\'\'''\'' -bg '\''\'\'''\''#111111'\''\'\'''\'''\'''