У меня был этот вариант использования для пары разных сценариев, которые я написал или модифицировал. По сути, я хочу, чтобы завершение bash для опции '-x' завершало выполнение исполняемых файлов в PATH. Это своего рода два вопроса, объединенные в один.
До сих пор у меня были проблемы, потому что bash не различает псевдонимы, встроенные функции, функции и т. Д. И исполняемые файлы в PATH. Функция-оболочка _commands
в / usr / share / bash-Завершение / bash_completion завершает все вышеперечисленное, но я не использую для работы с псевдонимами, встроенными функциями, функциями и т. Д. И хочу завершить только те команды, которые оказались исполняемыми на путь.
Так, например ... Если я введу 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 вы можете получить отсортированный список исполняемых файлов по PATH с print -rl -- ${(ko)commands}
. Похоже, мне не хватает как минимум 60+ исполнителей, вероятно, потому, что uniq -u
выгружает исполнителей с тем же именем, что и псевдонимы или функции.
Есть лучший способ сделать это? Либо лучшая команда для получения всех исполняемых файлов в 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 -r 's/([^:]+):*/find "\1" -maxdepth 1 -type f -executable -exec basename "{}" \\;\n/eg' <<< $PATH | sort | uniq
... Однако ваша попытка bash выглядела хорошо. Что не так с этим? Представление? - person hek2mgl   schedule 03.04.2015compgen -A function -abck
? - person hek2mgl   schedule 03.04.2015compgen -A function -abck
включает всевозможные команды (псевдонимы, встроенные функции, функции, ключевые слова, исполняемые файлы в PATH). Мне просто нужны исполняемые файлы по пути. Например, один из скриптов - это оболочка для пигментации. Я хочу иметь возможность легко выделять синтаксис в установленных скриптах. Завершение его до псевдонимов или ключевых слов было бы контрпродуктивным. В любом случае, это всего лишь один пример, но он у меня возникал в ряде ситуаций. - person Six   schedule 03.04.2015compgen -c
.. - person hek2mgl   schedule 03.04.2015compgen -c
то же самое, что иcompgen -A function -abck
. Я не думаю, что есть опция compgen для перечисления только исполняемых файлов, но было бы очень хорошо, если бы она была. - person Six   schedule 03.04.2015diff -u <(compgen -A function -abck) <(compgen -c)
- person hek2mgl   schedule 03.04.2015compgen -A function -abck
показывает кучу дубликатов. Попробуйте вот так, чтобы убрать все дубли:diff -u <(compgen -A function -abck | sort -u) <(compgen -c | sort -u)
. Ответьте на stackoverflow.com/questions/948008/, я думаю, немного вводил в заблуждение, потому что он должен бытьcompgen -c
для всего вышеперечисленного ... Верно? - person Six   schedule 03.04.2015