【问题标题】:zsh: command substitution, proper quoting and backslash (again)zsh:命令替换,正确的引用和反斜杠(再次)
【发布时间】:2015-04-22 17:07:53
【问题描述】:

(注意:这是我发布 zsh: Command substitution and proper quoting 的后续问题,但现在有一个额外的复杂问题)。

我有一个函数 _iwpath_helper,它向标准输出输出一个可能包含空格的路径。为了便于讨论,我们假设 _iwpath_helper 总是返回一个常量文本,例如

function _iwpath_helper
{
    echo "home/rovf/my directory with spaces"
} 

我还有一个函数 quote_stripped 需要一个参数,如果这个参数被引号包围,它会删除它们并返回剩余的文本。如果参数没有被引号括起来,它会原封不动地返回它。这是它的定义:

function quote_stripped 
{
    echo ${1//[\"\']/}
}

现在我通过以下方式组合这两个功能:

target=$(quote_stripped "${(q)$(_iwpath_helper)}")

(当然,在这个玩具示例中,'quote_stripped' 是不必要的,因为 _iwpath_helper 在这里不返回引号分隔的路径,但在实际应用程序中,有时会返回)。

现在的问题是变量 target 包含一个 real 反斜杠字符,即如果我做一个

echo +++$target+++

我明白了

+++home/rovf/my\ directory\ with\ spaces

如果我尝试

cd $target

我在我的系统上收到错误消息,即目录

home/rovf/my/ directory/ with/ spaces

不会存在。

(如果您想知道正斜杠的来源:我在 Cygwin 上运行,我猜在这种情况下 cd 命令只是将反斜杠解释为正斜杠,以便更好地适应 Windows 环境)。

我猜想实际出现在变量target 中的反斜杠是由我应用于$(_iwpath_helper) 的(q) 扩展标志引起的。我现在的问题是我不能简单地删除 (q),因为没有它,函数 quote_stripped 只会在参数 $1 上获取字符串的第一部分,直到第一个空格 (/home/rovf/my )。

我怎样才能正确地写这个?

【问题讨论】:

  • 我认为您需要一个更清晰的示例,其中需要引用和取消引用。您展示的 _iwpath_helper 函数只需 target=$(_iwpath_helper); cd $target 即可正常工作。

标签: zsh


【解决方案1】:

我认为您只是想避免尝试手动去除引号,并使用 (Q) 扩展标志。比较:

% v="a b c d"
% echo "$v"
a b c d
% echo "${(q)v}"
a\ b\ c\ d
% echo "${(Q)${(q)v}}"
a b c d

【讨论】:

    【解决方案2】:

    chepner 是对的:我试图取消引用字符串的方式很愚蠢(我在“Bourne Shell 方式”中想太多了),我应该使用 (Q) 标志。

    这是我的解决方案:

    target="${(Q)$(_iwpath_helper)}"
    

    不再需要 quote_stripped 函数......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-29
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 2022-11-25
      • 1970-01-01
      • 2012-05-17
      • 1970-01-01
      相关资源
      最近更新 更多