Bash 完成脚本帮助

Bash 完成脚本帮助

所以我刚刚开始学习 bash 补全脚本,并开始为一个我经常使用的工具编写一个脚本。首先,我使用一组选项列表构建了脚本:

_zf_comp() 
{
    local cur prev actions
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    actions="change configure create disable enable show"

    COMPREPLY=($(compgen -W "${actions}" -- ${cur}))  
    return 0
}
complete -F _zf_comp zf

这很好。接下来,我决定动态创建可用操作列表。我整理了以下命令:

zf | grep "Providers and their actions:" -A 100 | grep -P "^\s*\033\[36m\s*zf" | awk '{gsub(/[[:space:]]*/, "", $3); print $3}' | sort | uniq | awk '{sub("\-", "\\-", $1); print $1}' | tr \\n " " | sed 's/^ *\(.*\) *$/\1/'

它基本上做了以下事情:

  • 抓取“提供商及其操作:”之后的“zf”命令中的所有文本
  • 抓取所有以“zf”开头的行(我不得不在这里做一些花哨的工作,因为 ZF 命令以彩色打印)
  • 抓住命令的第二部分并删除其中的所有空格(空格部分可能不再需要)
  • 对列表进行排序
  • 删除所有重复项
  • 退出破折号(我在尝试调试问题时添加了它 - 可能不需要)
  • 修剪所有新线
  • 修剪所有前导和结尾空格

上述命令产生:

$ zf | grep "Providers and their actions:" -A 100 | grep -P "^\s*\033\[36m\s*zf" | awk '{gsub(/[[:space:]]*/, "", $3); print $3}' | sort | uniq | awk '{sub("\-", "\\-", $1); print $1}' | tr \\n " " | sed 's/^ *\(.*\) *$/\1/'
change configure create disable enable show 
$

因此在我看来,它生成的字符串与我原始脚本中的字符串完全相同。但是当我这样做时:

_zf_comp() 
{
    local cur prev actions
    COMPREPLY=()
    cur="${COMP_WORDS[COMP_CWORD]}"
    prev="${COMP_WORDS[COMP_CWORD-1]}"

    actions=`zf | grep "Providers and their actions:" -A 100 | grep -P "^\s*\033\[36m\s*zf" | awk '{gsub(/[[:space:]]*/, "", $3); print $3}' | sort | uniq | awk '{sub("\-", "\\-", $1); print $1}' | tr \\n " " | sed 's/^ *\(.*\) *$/\1/'`

    COMPREPLY=($(compgen -W "${actions}" -- ${cur}))  
    return 0
}
complete -F _zf_comp zf

我的自动完成功能开始出现问题。首先,它不会自动完成任何带有“n”的命令;其​​次,当它自动完成时(例如“zf create”),它不允许我在完成的命令上退格。

第一个问题让我完全不知所措。我认为第二个问题可能与彩色文本中的转义字符有关。

有什么想法吗?这让​​我抓狂了!

答案1

我发现有用的一件事是创建一个输出到另一个终端的调试功能:

debug() { echo "$@" >/dev/pts/0; }; export -f de

然后,您可以从完成函数内部使用变量内容等调用它,并且在测试时它不会干扰其自身的输出。

您可以尝试更改tr为使用引号,看看是否能解决您的“n”问题:

tr '\n' ' '

grep通过管道传输你的输出cat -v来查看是否缺少任何转义序列。

此外,如果您可以避免调用那么多外部命令,它可能会加快速度。

相关内容