在bash中引用字符串的一行程序

在bash中引用字符串的一行程序,bash,shell,quoting,Bash,Shell,Quoting,考虑以下bash函数: function quote { declare quoted=${1//\'/\'\\\'\'} echo "'$quoted'" } 此函数将参数包装在单引号中,并将每个现有单引号替换为字符串'\'': 功能体似乎可以写在一行中: function my_quote { echo "'${1//\'/\'\\\'\'}'" } 但是,由于某些原因,这不起作用: $ my_quote "a'b" 'a\'\\'\'b' 所以,我的问题是(

考虑以下bash函数:

function quote { 
    declare quoted=${1//\'/\'\\\'\'}
    echo "'$quoted'"
}
此函数将参数包装在单引号中,并将每个现有单引号替换为字符串
'\''

功能体似乎可以写在一行中:

function my_quote {
    echo "'${1//\'/\'\\\'\'}'"
}
但是,由于某些原因,这不起作用:

$ my_quote "a'b"
'a\'\\'\'b'
所以,我的问题是(1)为什么一行版本不起作用?和(2)有没有办法让它起作用,比如说,增加一些反斜杠

顺便说一句,如果您感到好奇,这段代码演示了为什么这样一个函数很有用:

foo="some string generated at runtime, possibly containing special characters"
cmd="somecommand $(quote "$foo")"
ssh user@host "$cmd"
(1) 这可能是bash在
中处理参数扩展的方式与在赋值中处理参数扩展的方式不同。我认为这实际上是一个bug,因为带引号的字符串没有正确地取消引号。如果在内部使用其他变量,例如

"${var//x/$other}"
(2) 这不是一条线的方式,只是另一种方式。你可以把变量放在其他地方,但在我看来,这仍然不是一条线

function my_quote {
    local r="'\''"
    echo "'${1//\'/$r}'"
}

你也可以在一个子shell下放置一个
回音
$()
,但这仍然是一个两行或两个命令。

我的直觉是\在
因此每个\\变为\”。但快速检查表明,复制\也不起作用。我注意到了局部变量的解决方案,但正如您所说的,它不是一条直线。echo子shell非常聪明,但我想知道是否有一个修复程序只涉及正确的引用/转义。请参阅
%q
说明符以
printf
function my_quote {
    local r="'\''"
    echo "'${1//\'/$r}'"
}