Попробовав собственный скрипт завершения, который, как я знаю, работает (я использую его каждый день) и столкнулся с той же проблемой (при настройке, аналогичной вашей), я решил просмотреть bash 4.1.источник, и нашел этот интересный блок в bash-4.1/builtins/read.def:edit_line()
:
old_attempted_completion_function = rl_attempted_completion_function;
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
if (itext)
{
old_startup_hook = rl_startup_hook;
rl_startup_hook = set_itext;
deftext = itext;
}
ret = readline (p);
rl_attempted_completion_function = old_attempted_completion_function;
old_attempted_completion_function = (rl_completion_func_t *)NULL;
Похоже, что перед вызовом readline()
функция сброса сбрасывается на ноль по какой-то причине, что только длинная борода может взломать bashзнать.Таким образом, выполнение этого с помощью встроенной функции read
может быть просто жестко запрограммировано для отключения.
EDIT : еще кое-что об этом: код переноса, чтобы остановить завершение в read
встроенные произошли между bash-2.05a и bash-2.05b.Я нашел это примечание в файле bash-2.05b/CWRU/changelog
этой версии:
- edit_line (вызывается read -e) теперь просто выполняет завершение имени файла readline, устанавливая для rl_attempted_completion_function значение NULL, поскольку, например, выполняет завершение командыпотому что первое слово в строке было не очень полезно
Я думаю, что это устаревшая оплошность, и поскольку программируемое завершение прошло долгий путь, то, что вы делаете, полезно.Может быть, вы можете попросить их добавить его обратно или просто исправить, если это будет возможно для того, что вы делаете.
Боюсь, у меня нет другого решения, кроме того, что вы делаете »Мы придумали до сих пор, но по крайней мере мы знаем , почему это не работает с read
.
EDIT2 : Да, вот патч, который я только чтопроверено, что, кажется, "работает".Пройдет все юнит-тесты и тесты reg и покажет, как вы ожидаете, этот вывод из вашего скрипта при запуске с использованием пропатченного bash:
$ ./tabcompl.sh
waiting for commands
-> **<TAB>**
TAB hit output should these this when words you
->
Как вы увидите, я только что закомментировал эти 4 строки и некоторый таймеркод для сброса rl_attempted_completion_function
, когда указано read -t
и происходит тайм-аут, который больше не нужен.Если вы собираетесь отправить Chet что-то, вы можете сначала удалить весь мусор rl_attempted_completion_function
, но это по крайней мере позволит вашему скрипту работать должным образом.
Patch:
--- bash-4.1/builtins/read.def 2009-10-09 00:35:46.000000000 +0900
+++ bash-4.1-patched/builtins/read.def 2011-01-20 07:14:43.000000000 +0900
@@ -394,10 +394,12 @@
}
old_alrm = set_signal_handler (SIGALRM, sigalrm);
add_unwind_protect (reset_alarm, (char *)NULL);
+/*
#if defined (READLINE)
if (edit)
add_unwind_protect (reset_attempted_completion_function, (char *)NULL);
#endif
+*/
falarm (tmsec, tmusec);
}
@@ -914,8 +916,10 @@
if (bash_readline_initialized == 0)
initialize_readline ();
+/*
old_attempted_completion_function = rl_attempted_completion_function;
rl_attempted_completion_function = (rl_completion_func_t *)NULL;
+*/
if (itext)
{
old_startup_hook = rl_startup_hook;
@@ -923,8 +927,10 @@
deftext = itext;
}
ret = readline (p);
+/*
rl_attempted_completion_function = old_attempted_completion_function;
old_attempted_completion_function = (rl_completion_func_t *)NULL;
+*/
if (ret == 0)
return ret;
Имейте в виду, что исправленный пакет должен быть распространен или предоставлен каким-либо образом, где бы люди ни использовали ваш сценарий ...