bash中的转义斜线已完成

jeb*_*jeb 5 bash autocomplete complete

我尝试使用bash complete内置函数来显示命令的不同选项。

当选项包含类似中的路径时,我会遇到问题-F/dev/null

目前我正在使用

#!/bin/bash

_xyz-completion ()
{
  local cur

  COMPREPLY=()   # Array variable storing the possible completions.
  cur=${COMP_WORDS[COMP_CWORD]}

  case "$cur" in
    -*)
    COMPREPLY=( $( compgen -W "-oOption1 -F/dev/null" -- $cur ) )
    ;;
  esac

  return 0
}

complete -F _xyz-completion -o filenames xyz
Run Code Online (Sandbox Code Playgroud)

如果-F已经输入,则Tab完成将成功完成。

但是,如果只-键入,则Tab显示

空-oOption1

但我希望看到

-F / dev / null -oOption1

我已经试过-F\/dev\/null-F//dev//null"-F/dev/null"-F\\\/dev\\\/null

这似乎只是一个显示问题,因为完成本身可以按预期工作。

我看不到如何适当地在`-F / dev / null`中转义斜线。


要评论评论:

1)

没关系,如果将-F替换为非选项(例如-Q),这也是一个问题。–本杰明W.

这不是问题,它本身-F看起来像一个选项complete,因为如果我将其更改为,它甚至会失败xOPTION1 xF/dev/null

2)

我想知道什么compgen -W“ -oOption1 -F / dev / null”-为您显示。

它显示(按预期)

-oOption1
-F / dev / null

如前所述,-F成功完成-F/dev/null

nit*_*ram 3

如果您-o filenamescomplete示例中删除该选项,则会按预期工作。这是有道理的,因为补全不是文件名。这是 bash 版本 5.0.2(1) 的情况。

所以:

#!/bin/bash

_xyz-completion ()
{
  local cur

  COMPREPLY=()   # Array variable storing the possible completions.
  cur=${COMP_WORDS[COMP_CWORD]}

  case "$cur" in
    -*)
    COMPREPLY=( $( compgen -W "-oOption1 -F/dev/null" -- $cur ) )
    ;;
  esac

  return 0
}

complete -F _xyz-completion xyz
Run Code Online (Sandbox Code Playgroud)

当有斜杠时,它会截断部分完成,这绝对看起来像是一个错误。并且只有在显示选项时,实际完成才能正确进行。

编辑:

进一步研究后,该filenames选项用于转义可能包含空格或其他中断字符的字符串。基本上清理 shell 的文件名。来自可编程完成内置手册页

-o filenames:

告诉 Readline compspec 生成文件名,因此它可以执行任何特定于文件名的处理(例如向目录名称添加斜杠、引用特殊字符或抑制尾随空格)。此选项旨在与 -F 指定的 shell 函数一起使用。

显然,这包括删除之前的所有内容,包括最后一个斜杠。

编辑2:

这是来自 bash 用于文件名补全的 readline 源代码的注释。我从https://git.savannah.gnu.org/git/bash.git的 bash 存储库得到了这个。大师,所以在撰写本文时是 5.0 补丁 3。

./lib/readline/complete.c 第 697 行

#!/bin/bash

_xyz-completion ()
{
  local cur

  COMPREPLY=()   # Array variable storing the possible completions.
  cur=${COMP_WORDS[COMP_CWORD]}

  case "$cur" in
    -*)
    COMPREPLY=( $( compgen -W "-oOption1 -F/dev/null" -- $cur ) )
    ;;
  esac

  return 0
}

complete -F _xyz-completion xyz
Run Code Online (Sandbox Code Playgroud)

对于文件名补全,它只想打印基本名称,即最后一个斜杠之后的所有内容。