![Можно ли настроить способ завершения имен каталогов в bash?](https://rvso.com/image/1288703/%D0%9C%D0%BE%D0%B6%D0%BD%D0%BE%20%D0%BB%D0%B8%20%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B8%D1%82%D1%8C%20%D1%81%D0%BF%D0%BE%D1%81%D0%BE%D0%B1%20%D0%B7%D0%B0%D0%B2%D0%B5%D1%80%D1%88%D0%B5%D0%BD%D0%B8%D1%8F%20%D0%B8%D0%BC%D0%B5%D0%BD%20%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3%D0%BE%D0%B2%20%D0%B2%20bash%3F.png)
Я хотел бы указать bash использовать специальный метод для выполнения автодополнения определенных имен каталогов. Например, bash вызовет мою программу для выполнения автодополнения, если путь начинается с "$$", и выполнит автодополнение обычным образом в противном случае.
Возможно ли это вообще? Как бы вы это реализовали?
Награда: Я был бы очень признателен за ответ на этот вопрос. Цель состоит в том, чтобы позволитьавтопрыжокдля завершения путей для всех команд, когда пользователь начинает их с определенного префикса. Так, например, при копировании файла из дальнего каталога, вы можете ввести:
cp $$patern + <Tab>
и автопрыжок завершится
cp /home/user/CompliCatedDireCTOry/long/path/bla/bla
и вам просто нужно будет добавить, куда вы хотите поместить файл. Конечно, я могу использовать комментарий ott, чтобы добавить его к нескольким конкретным командам, но если у кого-то есть идея получше, я буду очень благодарен.
решение1
Это можно сделать, переопределив привязку по умолчанию для TAB(^i). Сначала вам нужно переопределить привязку TAB, затем вам нужно создать функцию, которая вызывает вашу команду, и, наконец, вам нужно взять вывод этой команды и обновить переменную, содержащую текущую командную строку.
Эта функция берет текущую командную строку и изменяет последние два символа на «huugs».
function my_awesome_tab_completion_function () {
set -- $READLINE_LINE
command="$1"
shift
argument="$*"
argument_length=$(echo -n $argument | wc -c)
if echo $argument | grep '^$$' >/dev/null 2>&1; then
new_argument=$(echo $argument | sed 's/..$/huugs/') # put your autojump here
else
new_argument=$(compgen -d $argument)
fi
new_argument_length=$(echo -n $new_argument | wc -c)
READLINE_POINT=$(( $new_argument_length - $argument_length + $READLINE_POINT ))
READLINE_LINE="$command $new_argument"
}
В вашем примере вы, вероятно, захотите изменить строку new_argument так, чтобы она выглядела следующим образом:
new_argument=$(autojump $argument)
Теперь переопределим привязку ^i:
$ bind -x '"\C-i"':'my_awesome_tab_completion_function'
Теперь проверьте, работает ли это:
$ cd /ro<TAB>
changes my command to:
$ cd /root
так что нормальное завершение все еще работает, вы можете проверить часть $$, выполнив cd $$... и т. д.
Если у вас возникли проблемы, включите подробный режим:
$ set -x
Он распечатает все, что делает функция.
Я протестировал это на Ubuntu 11, используя bash 4.2.8(1)-release (по умолчанию).
решение2
Процедуру завершения bash можно запрограммировать как скрипт оболочки.
Вот пример скрипта оболочки, который заменит любой параметр $$[Tab]
на my replacement string
, но только для определенной команды mycommand
и только если параметр равен именно "$$":
_mycomplete()
{
if [ ${COMP_WORDS[COMP_CWORD]} == \$\$ ]
then
COMPREPLY='my replacement string'
fi
}
complete -o default -o bashdefault -F _mycomplete mycommand
Чтобы запустить скрипт, необходимо подключить его к bash source <file-name>
(или использовать команду dot), а затем:
mycommand $$[Tab] -> mycommand my replacement string
mycommand $$$[Tab] -> mycommand $$$ (beep)
mycommand whatever[Tab] -> (will complete "whatever" in the normal bash manner)
Чтобы это всегда работало для некоторых или всех пользователей, включите это в один изпроцедуры профиля bash.
Проблема с complete
командой в том, что она будет работать только для одного или нескольких имен команд, указанных в качестве параметров. Можно просто дать ей список всех команд, которые могут быть использованы пользователями, или в отчаянных случаях расширить /bin/* /usr/bin/* ~/bin/*
.
Протестировано на CentOS 5.5.
Этот простой скрипт основан на источниках, которые я перечислил в другом своем ответе - том, который был удален модератором studiohack. Если интересно, просто попросите его восстановить его.