Bash完成脚本帮助

所以我刚刚开始学习bash完成脚本,并开始为我所用的工具开发一个工具。 首先,我使用一系列选项构build脚本:

_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 

这工作正常。 接下来,我决定dynamic创build可用操作的列表。 我把以下命令放在一起:

 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命令以彩色打印)
  • 抓住命令的第二部分,并从中删除任何空格(空格部分可能不再需要)
  • sorting列表
  • 摆脱任何重复
  • 逃脱破折号(我试图debugging问题时添加了这个可能不需要)
  • 修剪所有新行
  • 修剪所有前导和结束的空间

上面的命令产生:

 $ 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 $ 

所以它在我看来就像它产生了和我原来的脚本一样的string。 但是当我这样做:

 _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”)时,它不会让我退回到已完成的命令上。

第一个问题我完全被困住了。 我想的第二个可能与彩色文本中的转义字符有关。

有任何想法吗? 这让我疯狂!

有一点我觉得有用的是创build一个debuggingfunction,输出到另一个terminal:

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

然后你可以在你的完成函数中调用variables的内容等等,在testing的时候不会干扰它自己的输出。

你可以尝试改变你的tr使用引号,看看是否解决了你的“n”问题:

 tr '\n' ' ' 

通过cat -vpipe道输出你的grep ,看看你是否遗漏了任何转义序列。

另外,如果你可以避免调用这么多的外部命令,它可能会加快速度。