![为什么 Bash readline 有时会尝试断章取义地解析命令的第二个单词?](https://linux22.com/image/49724/%E4%B8%BA%E4%BB%80%E4%B9%88%20Bash%20readline%20%E6%9C%89%E6%97%B6%E4%BC%9A%E5%B0%9D%E8%AF%95%E6%96%AD%E7%AB%A0%E5%8F%96%E4%B9%89%E5%9C%B0%E8%A7%A3%E6%9E%90%E5%91%BD%E4%BB%A4%E7%9A%84%E7%AC%AC%E4%BA%8C%E4%B8%AA%E5%8D%95%E8%AF%8D%EF%BC%9F.png)
我最近将所有点文件和设置迁移到了一台运行 Ubuntu 13.04 的新笔记本电脑,并且注意到了一种我以前从未见过的奇怪行为。从本质上讲,我的终端有时试图从右到左而不是正常的方式解析命令。它根本不一致,并且通常两次输入相同的命令会产生不同的输出。
例子:
⋯ www localwork cd ~/Downloads
bash: /home/goldenapples/Downloads: Is a directory
~ cd ~/Downloads
~ Downloads ls
因此,第一个命令似乎已被解析为cd ~; Downloads
,但第二次我输入相同的命令时,它工作得很好。
别名也会发生同样的情况。在这里我已经gp
别名为git push
:
~ Documents infostats-theme master gp
usage: git [--version] [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
[-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
[--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
[-c name=value] [--help]
<command> [<args>]
[...]
See 'git help <command>' for more information on a specific command.
The program 'push' is currently not installed. You can install it by typing:
sudo apt-get install heimdal-clients
~ Documents infostats-theme master gp
Counting objects: 22, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (14/14), 1.69 KiB, done.
Total 14 (delta 12), reused 0 (delta 0)
To [email protected]:janrain/statboard.git
cf86529..3208e21 HEAD -> master:wq
不知道那里发生了什么。我的 bash 别名在第一个示例中被处理,并且它正确地将行读取为git push
,但我不知道之后发生了什么。看起来它试图解析该命令git; push;
,因此它显示了 git 帮助屏幕,然后显示一条错误,指出未push
安装名为的程序。奇怪的是:之后立即输入相同的命令效果很好。
这是我一直在忍受的问题之一,因为它毫无意义。我似乎唯一能指出的是,当我打字特别快时,问题行为似乎就会发生,而放慢速度并重新输入命令有时会使其起作用。
我主要在 tmux 1.8 中使用 Bash,如果这有任何帮助的话。
更新:
将此行添加到我的.tmux.conf
:
set-option -g default-command "exec /bin/bash --norc"
似乎已经解决了这个问题......或者至少从那以后我再也无法引起它了。但我仍然不知道为什么或如何,我希望得到解释。
答案1
看起来有些东西正在将空格解析为返回。
您可以从这种情况中删除 tmux(尝试在控制台或虚拟终端中工作)吗?
另外,检查 IFS 的设置,因此:
$ echo ":$IFS:" | cat -vte
: ^I$
:$
(所以,空格、TAB、回车)。
任何其他有问题的命令是否具有别名或作为与命令同名的函数实现?
尝试“\cd ...”或“命令 cd”来解决。
另外,为了进行诊断,请尝试使用 TAB 键代替空格来代替命令内的空白,和/或使用换行 (Ctrl-J) 代替 Return (Ctrl-M)。
答案2
要调试此类问题,您可以尝试打开 bash 在解析输入期间处理的命令和输入行的打印:
set -v -x
要再次将其关闭,您可以使用set +v +x
.有时后台会发生一些很奇怪的事情。