比方说,你有一个Bash别名:
alias rxvt='urxvt'
这很好。
然而:
alias rxvt='urxvt -fg '#111111' -bg '#111111''
不管用,也不管用:
alias rxvt='urxvt -fg \'#111111\' -bg \'#111111\''
那么,一旦有转义引号,如何在字符串中匹配开始和结束引号呢?
alias rxvt='urxvt -fg'\''#111111'\'' -bg '\''#111111'\''
看起来很笨拙,但如果允许像这样连接它们,它将表示相同的字符串。
恕我直言,真正的答案是你不能在单引号字符串中转义单引号。
它是不可能的。
如果我们假设使用bash。
从bash手册…
Enclosing characters in single quotes preserves the literal value of each
character within the quotes. A single quote may not occur
between single quotes, even when preceded by a backslash.
您需要使用其他字符串转义机制之一"或\
没有什么神奇的关于别名要求它使用单引号。
以下两种方法都可以在bash中工作。
alias rxvt="urxvt -fg '#111111' -bg '#111111'"
alias rxvt=urxvt\ -fg\ \'#111111\'\ -bg\ \'#111111\'
后者使用\来转义空格字符。
#111111要求单引号也没有什么神奇之处。
下面的选项实现了与其他两个选项相同的结果,因为rxvt别名按预期工作。
alias rxvt='urxvt -fg "#111111" -bg "#111111"'
alias rxvt="urxvt -fg \"#111111\" -bg \"#111111\""
您还可以直接逃避麻烦的#
alias rxvt="urxvt -fg \#111111 -bg \#111111"
这是另一个解决方案。这个函数将接受一个参数,并使用单引号字符适当地引用它,就像上面被投票的答案解释的那样:
single_quote() {
local quoted="'"
local i=0
while [ $i -lt ${#1} ]; do
local ch="${1:i:1}"
if [[ "$ch" != "'" ]]; then
quoted="$quoted$ch"
else
local single_quotes="'"
local j=1
while [ $j -lt ${#1} ] && [[ "${1:i+j:1}" == "'" ]]; do
single_quotes="$single_quotes'"
((j++))
done
quoted="$quoted'\"$single_quotes\"'"
((i+=j-1))
fi
((i++))
done
echo "$quoted'"
}
所以,你可以这样用:
single_quote "1 2 '3'"
'1 2 '"'"'3'"'"''
x="this text is quoted: 'hello'"
eval "echo $(single_quote "$x")"
this text is quoted: 'hello'
我并没有特别提到引用问题,因为,有时候,考虑另一种方法是合理的。
rxvt() { urxvt -fg "#${1:-000000}" -bg "#${2:-FFFFFF}"; }
你可以调用它为:
rxvt 123456 654321
这个想法是你现在可以在不考虑引号的情况下使用别名:
alias rxvt='rxvt 123456 654321'
或者,如果你出于某种原因需要在所有调用中包含#:
rxvt() { urxvt -fg "${1:-#000000}" -bg "${2:-#FFFFFF}"; }
你可以调用它为:
rxvt '#123456' '#654321'
那么,当然,别名是:
alias rxvt="rxvt '#123456' '#654321'"
(哦,我想我确实提到了引用:)