【发布时间】:2015-06-08 14:22:25
【问题描述】:
我已经为我编写或修改的几个不同的脚本提出了这个用例。本质上,我希望选项“-x”的 bash 完成以完成 PATH 上的可执行文件。这是一个包含两个问题的问题。
到目前为止,我遇到了一些麻烦,因为 bash 不能轻易地区分别名、内置函数、函数等和 PATH 上的可执行文件。 /usr/share/bash-completion/bash_completion 中的_commands 包装函数完成了上述所有操作,但我没有使用别名、内置函数、函数等,只想完成碰巧的命令PATH 上的可执行文件。
例如...如果我输入scriptname -x bas[TAB],它应该以base64、bash、basename、bashbug 完成。
这是我的完成脚本现在的样子:
_have pygsparkle && {
_pygsparkle(){
local cur prev
COMPREPLY=()
cur=${COMP_WORDS[COMP_CWORD]}
prev=${COMP_WORDS[COMP_CWORD-1]}
case $prev in
-x|--executable)
# _command
executables=$({ compgen -c; compgen -abkA function; } | sort | uniq -u)
COMPREPLY=( $( compgen -W "$executables" -- "$cur" ) )
return 0
;;
esac
if [[ $cur = -* ]]; then
COMPREPLY=( $( compgen -W '--executable -h --help -x' -- "$cur" ) )
fi
}
complete -F _pygsparkle pygsparkle
}
它似乎按预期工作,但{ compgen -c; compgen -abkA function; } | sort | uniq -u 是一个非常肮脏的黑客。在 zsh 中,您可以获得运行 print -rl -- ${(ko)commands} 的 PATH 上的可执行文件的排序列表。所以看来我至少缺少 60 多个 exec,可能是因为 uniq -u 正在转储与别名或函数同名的 exec。
有没有更好的方法来做到这一点?是获取 PATH 上所有可执行文件的更好命令,还是服务于相同目的的预先存在的完成函数?
更新: 好的,所以下面的函数在 1/6 秒内执行,看起来是最好的选择。除非有任何其他建议,否则我可能会直接关闭问题。
_executables(){
while read -d $'\0' path; do
echo "${path##*/}"
done < <(echo -n "$PATH" | xargs -d: -n1 -I% -- find -L '%' -maxdepth 1 -mindepth 1 -type f -executable -print0 2>/dev/null) | sort -u
}
【问题讨论】:
-
如果您在末尾设置
:可选,sed 命令将起作用:sed -r 's/([^:]+):*/find "\1" -maxdepth 1 -type f -executable -exec basename "{}" \\;\n/eg' <<< $PATH | sort | uniq... 但是,您的 bash 尝试看起来不错。那有什么问题?表现如何? -
运行大量的 find 命令来完成在实践中似乎并不能很好地工作,每个 [TAB] 都会冻结终端几秒钟。只是希望已经有一个完成功能或选项可以做得更好,否则我可能不得不废弃它。
-
我真的不明白
compgen -A function -abck有什么问题? -
compgen -A function -abck包括各种命令(别名、内置命令、函数、关键字、PATH 上的可执行文件)。我只想要路径上的可执行文件。例如,其中一个脚本是 pygmentize 的包装器。我希望能够轻松地对已安装的脚本进行语法突出显示。让别名或关键字完整会适得其反。无论如何,这只是一个例子,但我在很多情况下都遇到过。 -
然后只使用
compgen -c..
标签: linux bash shell completion