cli代码如下:
#!/bin/bash cmd1() { echo $FUNCNAME: "$@" } cmd2() { echo $FUNCNAME: "$@" } cmdN() { echo $FUNCNAME: "$@" } __complete() { echo $allowed_commands } shopt -qs extglob fn_hide_prefix='__' allowed_commands="$(declare -f | sed -ne '/^'$fn_hide_prefix'.* ()/!s/ ().*//p' | tr '\n' ' ')" complete -D -W "this should output these words when you hit TAB" echo "waiting for commands" while read -ep"-> "; do history -s $REPLY case "$REPLY" in @(${allowed_commands// /|})?(+([[:space:]])*)) $REPLY ;; \?) __complete ;; *) echo "invalid command: $REPLY" ;; esac done
澄清:在Bash 4中制作和测试
所以,“读-e”给出readline功能,我可以调用命令,编辑输入行等。我不能做任何方式是让readline的选项卡完成工作!
我试过两件事:
>应该如何应该做:使用bash内置“完整”和“compgen”,报告工作here更新:它不报告在脚本中工作。
> This ugly workaround
当在脚本中使用“完整”时,为什么readline不正确?它的工作原理,当我尝试从bash在交互模式…
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()被调用之前,它会将完成函数重置为null,因为只有一个bash-hacking长胡子可能知道。因此,使用读取内置函数执行此操作可以简单地硬编码为禁用。
编辑:更多关于此:在读内置中停止完成的包装代码发生在bash-2.05a和bash-2.05b之间。我在该版本的bash-2.05b / CWRU / changelog文件中发现了此注释:
- edit_line (called by read -e) now just does readline’s filename completion by setting rl_attempted_completion_function to NULL,since e.g.,doing command completion for the first word on the line wasn’t really useful
我认为这是一个遗留的监督,并且由于可编程完成已经走了很长的路,你在做什么是有用的。也许你可以让他们把它添加回来,或者只是补丁自己,如果这是可行的你正在做什么。
害怕我没有一个不同的解决方案,除了你到目前为止,但至少我们知道为什么它不工作与读。
编辑2:对,这里是一个补丁,我只是测试,似乎“工作”。通过所有单元和reg测试,并显示您的脚本使用修补的bash运行时的输出,如你所料:
$ ./tabcompl.sh waiting for commands -> **<TAB>** TAB hit output should these this when words you ->
正如你将看到的,我只是注释掉这4行和一些计时器代码,以便在指定读-t时重置rl_attempted_completion_function,并且不再需要超时。如果你要发送Chet的东西,你可能希望先切除rl_attempted_completion_function垃圾,但这至少会让你的脚本正常运行。
补丁:
--- 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;
请记住,修补的bash将不得不分发或提供某种程度上人们将使用您的脚本… …