Search code examples
bashsyntaxquoting

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.


Solution

  • 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:

    $ echo 'abc''123'  
    abc123
    $ echo 'abc'\''123'
    abc'123
    $ echo 'abc'"'"'123'
    abc'123
    

    It will also keep the internal representation with 'to be joined' strings, and will also prefer the shorter escape syntax when possible:

    $ alias test='echo '"'"'hi'"'"
    $ alias test
    alias test='echo '\''hi'\'''
    $ test
    hi