我有一个奇怪的问题,并且真的不知道如何在 StackExchange 上搜索类似的问题。
这与Ubuntu 20.04 command-line
.
当我按下TAB
键时,“自动完成”会附加非常奇怪的结果作为“当前命令的输入”的一部分。
例如:
Typing: (cd and pressing TAB afterwards)
....
cd words=("${@:3:2}")
cword="$3"
cur="$3"
cur="$3"
cword="$3"
prev="$3"
words=("${@:3:2}")
stage^C
打字时也一样bash + TAB
bash words=("${@:3:2}")
cword="$3"
cur="$3"
cur="$3"
cword="$3"
prev="$3"
words=("${@:3:2}")
^C
Shell 自动完成功能最近表现得很奇怪,不知道如何修复。(再次道歉,我真的不知道如何正确表述这个问题,甚至找不到类似的问题)。
笔记:
reset
只清除了控制台,但之后问题仍然存在!
答案1
我假设你的 shell 是 Bash。我可以通过eval
像这样重新定义来复制您的问题:
eval() { echo "$1"; }
或类似的。完成函数使用eval
.他们期望eval
成为eval
这外壳内置。如果eval
被篡改,他们可能会行为不端。
我的测试表明,eval
作为别名或可执行文件不会破坏完成,因此它很可能是您的情况下的函数。
调用
type eval
正常情况下输出应该是eval is a shell builtin
.如果你得到eval is a function
然后调用
unset -f eval
并检查完成是否表现更好(或至少不同)。
您应该调查该函数来自哪里。手动方法是检查启动文件(~/.bashrc
等等)以及他们采购的所有东西。还有更好的方法。像这样进行:
shopt -s extdebug # enable extra debugging info
declare -F eval
这将告诉您行号和源文件。 (最后运行shopt -u extdebug
以禁用调试。)
上面的方法应该足以定位函数的定义。为了以防万一,这里还有一些其他方法:如何查找定义 bash 函数的文件。
找到该函数的定义后eval
,将其删除并让其eval
成为内置函数。笔记:
- 删除定义不会自动修复已经运行的 shell。产生一个新的外壳;注销并登录;如有疑问,请重新启动。
- 删除定义会破坏任何实际需要该函数的内容,因此可能需要进一步调查:该函数存在的原因是什么?考虑重命名而不是删除(至少在最初,暂时),以防定义中的代码不是可消耗的。
- 该函数可以被定义多次(并且最近来源的定义获胜)。如果删除定义没有恢复内置函数,则可能还剩下一个定义。重复该方法。
如果补全未完全修复,请检查输出declare -F
并检查替换内置函数的其他函数(使用compgen -b
知道要搜索什么)。如果需要,请像刚才那样分析它们eval
并进行类似的修复。
答案2
当我错过了空格set -o vi
并输入了时,我就遇到了这种情况set -ovi
。这导致 bash 的 set 内置函数将 解释为v
发送到 set 的另一个选项。来自GNU 手册页集:
-v 在读取 shell 输入行时打印它们。
注销系统时会出现另一个症状,屏幕上会打印以下内容:
logout
# ~/.bash_logout: executed by bash(1) when login shell exits.
# when leaving the console clear the screen to increase privacy
if [ "$SHLVL" = 1 ]; then
[ -x /usr/bin/clear_console ] && /usr/bin/clear_console -q
fi