Let\'s say, you have a Bash alias
like:
alias rxvt=\'urxvt\'
which works fine.
However:
I'm not specifically addressing the quoting issue because, well, sometimes, it's just reasonable to consider an alternative approach.
rxvt() { urxvt -fg "#${1:-000000}" -bg "#${2:-FFFFFF}"; }
which you can then call as:
rxvt 123456 654321
the idea being that you can now alias this without concern for quotes:
alias rxvt='rxvt 123456 654321'
or, if you need to include the #
in all calls for some reason:
rxvt() { urxvt -fg "${1:-#000000}" -bg "${2:-#FFFFFF}"; }
which you can then call as:
rxvt '#123456' '#654321'
then, of course, an alias is:
alias rxvt="rxvt '#123456' '#654321'"
(oops, i guess i kind of did address the quoting :)
in addition to @JasonWoof perfect answer i want to show how i solved related problem
in my case encoding single quotes with '\''
will not always be sufficient, for example if a string must quoted with single quotes, but the total count of quotes results in odd amount
#!/bin/bash
# no closing quote
string='alecxs\'solution'
# this works for string
string="alecxs'solution"
string=alecxs\'solution
string='alecxs'\''solution'
let's assume string is a file name and we need to save quoted file names in a list (like stat -c%N ./* > list)
echo "'$string'" > "$string"
cat "$string"
but processing this list will fail (depending on how many quotes the string does contain in total)
while read file
do
ls -l "$file"
eval ls -l "$file"
done < "$string"
workaround: encode quotes with string manipulation
string="${string//$'\047'/\'\$\'\\\\047\'\'}"
# result
echo "$string"
now it works because quotes are always balanced
echo "'$string'" > list
while read file
do
ls -l "$file"
eval ls -l "$file"
done < list
Hope this helps when facing similar problem
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 '
:
'
End first quotation which uses single quotes."
Start second quotation, using double-quotes.'
Quoted character."
End second quotation, using double-quotes.'
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.
Both versions are working, either with concatenation by using the escaped single quote character (\'), or with concatenation by enclosing the single quote character within double quotes ("'").
The author of the question did not notice that there was an extra single quote (') at the end of his last escaping attempt:
alias rxvt='urxvt -fg'\''#111111'\'' -bg '\''#111111'\''
│ │┊┊| │┊┊│ │┊┊│ │┊┊│
└─STRING──┘┊┊└─STRIN─┘┊┊└─STR─┘┊┊└─STRIN─┘┊┊│
┊┊ ┊┊ ┊┊ ┊┊│
┊┊ ┊┊ ┊┊ ┊┊│
└┴─────────┴┴───┰───┴┴─────────┴┘│
All escaped single quotes │
│
?
As you can see in the previous nice piece of ASCII/Unicode art, the last escaped single quote (\') is followed by an unnecessary single quote ('). Using a syntax-highlighter like the one present in Notepad++ can prove very helpful.
The same is true for another example like the following one:
alias rc='sed '"'"':a;N;$!ba;s/\n/, /g'"'"
alias rc='sed '\'':a;N;$!ba;s/\n/, /g'\'
These two beautiful instances of aliases show in a very intricate and obfuscated way how a file can be lined down. That is, from a file with a lot of lines you get only one line with commas and spaces between the contents of the previous lines. In order to make sense of the previous comment, the following is an example:
$ cat Little_Commas.TXT
201737194
201802699
201835214
$ rc Little_Commas.TXT
201737194, 201802699, 201835214
Since one cannot put single quotes within single quoted strings, the simplest and most readable option is to use a HEREDOC string
command=$(cat <<'COMMAND'
urxvt -fg '#111111' -bg '#111111'
COMMAND
)
alias rxvt=$command
In the code above, the HEREDOC is sent to the cat
command and the output of that is assigned to a variable via the command substitution notation $(..)
Putting a single quote around the HEREDOC is needed since it is within a $()