【问题标题】:How can I ensure my autocompleted spaces are fed into my function properly?如何确保我的自动完成空间正确输入到我的函数中?
【发布时间】:2023-03-04 11:34:02
【问题描述】:

我正在使用zsh,并且正在尝试编写一个函数来对 URL 和路径名进行操作:

function my-function
{
  somecommand --url $1 $(readlink -f $2)
}

(为了让事情有些复杂,该函数实际上使用了sh 语法,因为它来自我的~/.zshrc 使用a trick like this)。 readlink 用于扩展符号链接并确保正确评估诸如. 之类的目录(存储目录名称以供somecommand 以后使用)。

当我像这样从命令行键入命令时:

my-function http://example.org/example /tmp/myexampledirectory

...即使我自动完成目录名称,它也可以正常工作。但是,如果目录名称包含空格,zsh 会这样完成:

my-function http://example.org/example /tmp/My\ Example\ Directory

对于大多数“正常”命令(cp、mv 等),似乎永远不会导致问题。但是,就我而言,somecommand 将 $2 视为仅是 /tmp/My - 大概其余的被视为另一个参数。

如何避免这种情况?我希望 改变标准的zsh 自动完成功能,而是为我的函数找到一种方法来处理这个问题。

【问题讨论】:

    标签: autocomplete scripting sh zsh


    【解决方案1】:

    zsh补全系统在这里效果很好,解决方法也很简单,只需在脚本中的readlink参数两边加上双引号即可:

    somecommand --url $1 $(readlink -f "$2")
    

    关键是没有引号readlink 会删除转义空格的反斜杠。比较三个结果:

    1. 没有反斜杠和引号readlink -f 假定存在三个不同的文件/目录(在当前目录中具有默认路径)并生成

    $ readlink -f /tmp/My Example Directory
    /tmp/My
    /home/jimmij/Example
    /home/jimmij/Directory
    

    2. 带有转义反斜杠但不带引号的readlink -f 理解只有一个目录,但会从输出中删除反斜杠,因此somecommand 需要三个单独的参数

    $ readlink -f /tmp/My\ Example\ Directory
    /tmp/My Example Directory
    

    3. 带有反斜杠和双引号的readlink -f 给出带有反斜杠的输出(很可能是somecommand 所期望的)

    $ readlink -f "/tmp/My\ Example\ Directory"
    /tmp/My\ Example\ Directory
    

    顺便说一句,根据经验:如果在类似 shell 的脚本(bash、zsh 等)中的空格有任何问题,首先要使用不同的引号将变量括起来。

    【讨论】:

    • $2 不需要引用,因为参数扩展(默认情况下)在zsh 中不会进行分词。但是,命令替换可以。 somecommand --url $1 "$(readlink -f $2)"(当然,引用$2 也不会伤害。)
    • 顺便说一句,“玩引号”并不能很好地替代理解需要引用的内容和原因。
    • (3) 实际上不起作用。如果我这样做(来自 bash)readlink -f "/tmp/my\ dir/with\ spaces/",我只会得到一个返回码 1。不过,正如@chepner 建议的那样,在整个 readlink 表达式周围放置空格确实有效。
    猜你喜欢
    • 2019-12-01
    • 1970-01-01
    • 2022-07-21
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 2016-10-05
    • 2020-07-29
    • 2021-08-20
    相关资源
    最近更新 更多