bash - 在 bash 中转义斜杠完成

标签 bash autocomplete bash-completion

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

I have problems when an option contains a path like in -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

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

但是如果只输入-,那么会显示一个Tab

null       -oOption1

但我希望看到

-F/dev/null       -oOption1

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

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

我看不出如何适本地转义 `-F/dev/null` 中的斜杠。


评论评论:

1)

Never mind, it's a problem also if -F is replaced by a non-option such as -Q. – Benjamin W.

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

2)

I'm wondering what compgen -W "-oOption1 -F/dev/null" -- - displays for you.

它显示(如预期的那样)

-oOption1
-F/dev/null

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

最佳答案

如果您从 complete 中删除 -o filenames 选项,您的示例将按预期工作。这是有道理的,因为补全不是文件名。这是 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

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

编辑:

进一步研究后,filenames 选项用于转义可能包含空格或其他中断字符的字符串。基本上清理 shell 的文件名。来自Programmable Completion Built-in man page

-o 文件名:

Tell Readline that the compspec generates filenames, so it can perform any filename-specific processing (like adding a slash to directory names, quoting special characters, or suppressing trailing spaces). This option is intended to be used with shell functions specified with -F.

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

编辑2:

这是来自 bash 用于文件名完成的 readline 源的注释。我从 https://git.savannah.gnu.org/git/bash.git 的 bash 仓库中得到了这个).主人,所以在撰写本文时是 5.0 补丁 3。

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

/* Return the portion of PATHNAME that should be output when listing
   possible completions.  If we are hacking filename completion, we
   are only interested in the basename, the portion following the
   final slash.  Otherwise, we return what we were passed.  Since
   printing empty strings is not very informative, if we're doing
   filename completion, and the basename is the empty string, we look
   for the previous slash and return the portion following that.  If
   there's no previous slash, we just return what we were passed. */
static char *
printable_part (char *pathname)

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

关于bash - 在 bash 中转义斜杠完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55476845/

相关文章:

python 运行 bash 命令得到不好的结果

javascript - 无法从 md-autocomplete 中的对象数组中获取值

javascript - 允许 typeahead,js 自动完成文本中的单词,而不仅仅是下拉列表中的单个值

bash - 使用很长的逗号分隔的数字字符串将文件拆分为多个文件

android - 如何以正确的方式将 UTF8 格式化为主题 header ?

javascript - Jquery ui 自动完成 - 多个来源

bash - 为 compgen 指定另一个目录以自动完成目录,而不是使用 pwd

bash - 仅向用户显示 COMPREPLY bash 完成选项的子字符串

linux - 如何在 SLES 12 中自动完成命令的选项?

linux - 通过 SSH 通过 STDIN 将指示器从 Bash 传回 Perl