Suppose you have a Bash alias for example:
alias rxvt='urxvt'
Good results.
However:
alias rxvt='urxvt -fg '#111111' -bg '#111111''
It will not work, nor will it:
alias rxvt='urxvt -fg \'#111111\' -bg \'#111111\''
So, once the quotes are escaped, how do you eventually match the start and end quotes in the string?
alias rxvt='urxvt -fg'\''#111111'\'' -bg '\''#111111'\''
It looks awkward, though if you allow them to be concatenated, it will represent the same string.
#1st floor
I didn't see this entry on his blog (link?)But according to gnu reference manual :
Including characters in single quotation marks ('') preserves the literal value of each character within the quotation marks.Even a backslash before a single quotation mark cannot cause a single quotation mark between single quotations.
So bash can't understand:
alias x='y \\'z '
However, if caused by double quotation marks, you can do the following:
alias x="echo \'y " > x > 'y
#2nd floor
If you do want to use single quotation marks on the outside, remember that you can paste both at the same time.Example:
alias rxvt='urxvt -fg '"'"'#111111'"'"' -bg '"'"'#111111'"'" # ^^^^^ ^^^^^ ^^^^^ ^^^^ # 12345 12345 12345 1234
How does'''mean only':
- 'End with single quotation marks.
- "Use double quotation marks to start the second quotation mark.
- 'Reference character.
- "Use double quotation marks to end the second quotation mark.
- 'Use single quotation marks to cause the third quotation mark.
If you do not place any spaces between (1) and (2) or between (4) and (5), Shell interprets the string as a long word.
#3rd floor
I don't specifically address quotation issues because sometimes it makes sense to consider alternatives.
rxvt() { urxvt -fg "#${1:-000000}" -bg "#${2:-FFFFFF}"; }
You can call it:
rxvt 123456 654321
The idea is that you can alias this now without worrying about quotation marks:
alias rxvt='rxvt 123456 654321'
Or, if for some reason you need to include # in all calls:
rxvt() { urxvt -fg "${1:-#000000}" -bg "${2:-#FFFFFF}"; }
You can call it:
rxvt '#123456' '#654321'
Then, of course, the alias is:
alias rxvt="rxvt '#123456' '#654321'"
(Bad, I think I did solve the problem:)
#4th floor
I always replace each embedded single quotation mark with a sequence only:'\'(that is, quotation backslash quotation marks), which closes the string, appends the escaped single quotation mark, and reopens the string.
I often whip a quote function in my Perl script to do this for me.The steps will be:
s/'/'\\''/g # Handle each embedded quote $_ = qq['$_']; # Surround result with single quotes.
This handles almost everything.
Life becomes more interesting when eval is introduced into shell scripts.Basically you have to re-quote everything!
For example, create a Perl script named quotify that contains the following statements:
#!/usr/bin/perl -pl s/'/'\\''/g; $_ = qq['$_'];
Then use it to generate a properly referenced string:
$ quotify urxvt -fg '#111111' -bg '#111111'
Result:
'urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''
You can then copy/paste it into the alias command:
alias rxvt='urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''
(If you need to insert a command into the evaluation, run quotify again:
$ quotify alias rxvt='urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''
Result:
'alias rxvt='\''urxvt -fg '\''\'\'''\''#111111'\''\'\'''\'' -bg '\''\'\'''\''#111111'\''\'\'''\'''\'''
You can copy/paste it into the assessment:
eval 'alias rxvt='\''urxvt -fg '\''\'\'''\''#111111'\''\'\'''\'' -bg '\''\'\'''\''#111111'\''\'\'''\'''\'''
#5th floor
Because Bash 2.04 The syntax $'string'(not'string'); warning: do not confuse with $('string') is another reference mechanism that allows ANSI C-like escape sequences And expanded to single quote version.
Simple examples:
$> echo $'aa\'bb' aa'bb $> alias myvar=$'aa\'bb' $> alias myvar alias myvar='aa'\''bb'
In your case:
$> alias rxvt=$'urxvt -fg \'#111111\' -bg \'#111111\'' $> alias rxvt alias rxvt='urxvt -fg '\''#111111'\'' -bg '\''#111111'\'''
Common escape sequences work as expected:
\' single quote \" double quote \\ backslash \n new line \t horizontal tab \r carriage return
The following documents are copied and pasted in man bash (version 4.4):
Words in the $'string'form are specially processed.The word expands to a string and replaces the backslash escape character as specified in the ANSI C standard.The backslash escape sequence (if present) is decoded as follows:
\a alert (bell) \b backspace \e \E an escape character \f form feed \n new line \r carriage return \t horizontal tab \v vertical tab \\ backslash \' single quote \" double quote \? question mark \nnn the eight-bit character whose value is the octal value nnn (one to three digits) \xHH the eight-bit character whose value is the hexadecimal value HH (one or two hex digits) \uHHHH the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits) \UHHHHHHHH the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits) \cx a control-x character
The result is a single quotation mark, as if there were no dollar signs.
For more details, see the Quotes and Escapes: Strings similar to ANSI C .Also note that "Bash Change" Files ( Overview here ) Many changes and bug fixes related to the $'string'reference mechanism have been mentioned.
According to unix.stackexchange.com, How do I use special characters as common characters? It should work in bash, zsh, mksh, ksh93 and FreeBSD and busybox sh (with some variations).