如何获得较长的命令行以换行到下一行?


108

长期以来,我在Ubuntu中注意到的一件令我感到沮丧的事情是,当我在命令行输入比终端宽度更长(更宽)的命令时,它没有换行,而是返回到新行。同一行上的第1列,并开始覆盖命令行的开头。(它实际上不会覆盖实际的命令,但是在视觉上,它会覆盖显示的文本)。

很难不看就难以解释,但可以说我的终端宽20个字符(我的终端更像是120个字符-只是为了举例),我想回显英文字母。我输入的是这样的:

echo abcdefghijklmnopqrstuvwxyz

但是在按下键之前,我的终端看起来是:

pqrstuvwxyzghijklmno

当我按下回车键时,它回显

abcdefghijklmnopqrstuvwxyz

所以我知道命令已正确接收。它只是在“ o”后面加上了我的输入内容,然后从同一行开始。

如果我在只有20个字符的终端上键入此命令,将会发生以下情况:

echo abcdefghijklmno
pqrstuvwxyz

背景:我正在使用bash作为外壳,并且〜/ .bashrc中有以下行:

set -o vi

以便能够使用VI命令浏览命令行。我当前正在使用Ubuntu 10.10服务器,并使用Putty连接到服务器。

在我工作过的任何其他环境中,如果键入长命令行,当命令的长度超过终端宽度时,它将在正在处理的行下添加新行,并且当我继续键入时,我可以看到命令2条不同的线。但只要我记得使用Ubuntu,我的长命令仅占用1行。

当我返回历史记录中的先前命令时也会发生这种情况(我按Esc,然后按“ K”以返回先前的命令)-当我获得的长度大于终端宽度的先前命令时,命令行乱了,我无法告诉我命令中的位置。

我发现看到整个长命令的唯一解决方法是单击“ Esc-V”,这会在VI编辑器中打开当前命令。

我认为.bashrc文件中没有奇怪的地方。我注释掉了“ set -o vi”这一行,但仍然有问题。

我下载了一份新的Putty副本,但未对配置进行任何更改-我只是键入主机名以进行连接,但仍然存在问题,因此我认为Putty无关紧要(除非我需要进行一些配置更改)

还有其他人有这个问题吗?有人可以考虑如何解决这个问题吗?

编辑

这是我的.bashrc文件。我已经在机器之间复制了相同的配置文件,并且在$ PS1中使用了特殊字符,这些特殊字符会以某种方式将其丢弃。我现在坚持使用我的$ PS1的标准bash变量。

感谢@ændrük在.bashrc上的提示!

...结束编辑...


1
为确保问题不是由您的.bashrc文件引起的,我建议暂时将其替换为的副本/etc/skel/.bashrc。请记住,您需要重新连接才能使更改生效,并确保保留自己的.bashrc的备份。
ændrük

1
您正在使用哪个终端应用程序?您描述的行为是不正常的,当然不是默认行为。
若奥·平托

在我曾经使用过的Shell中(以及在Cisco CLI中),即使它不在屏幕上,您也可以按Ctrl-L重新显示所输入的行。在您的情况下,这可能仍然会导致您正在谈论的输出中断,但是我很好奇。
belacqua

3
随意创建一个“答案”来解释解决方案并将其标记为已接受。看起来有些愚蠢,但是有一个正确的答案可以帮助保持网站的有条理,并可能在将来更有效地指导其他有类似问题的人。
ændrük

按照serverfault上的此答案,请使用tput smam
Samveen

Answers:


136

确保PS1中所有不可打印的字节都包含在中\[ \]。否则,bash将在提示时将其计数。它使用提示的长度来确定何时换行。

例如,这里bash将提示计数为19列宽,而终端显示的提示仅10列宽(My prompt用青色>写,并用默认颜色写):

PS1='\e[36mMy prompt\e[0m>'         # bash count: 19, actual: 10

而在这里它仅将提示计数为10列宽,因为它忽略了特殊字符\[\]转义字符之间的字节:

PS1='\[\e[36m\]My prompt\[\e[0m\]>' # bash count: 10, actual: 10

不过,为了获得良好的实践,请使用tput生成终端转义而不是对其进行硬编码:

cyan=$(tput setaf 6) # \e[36m
reset=$(tput sgr0)   # \e[0m
PS1='\[$cyan\]My prompt\[$reset\]>'

http://mywiki.wooledge.org/BashFAQ/053,也http://wiki.bash-hackers.org/scripting/terminalcodes更多关于tput


3
这很好地解释了无法接受的答案的问题
Jamie Cook

在代码的最后一行PS1='...':为什么单引号不能阻止$cyan$reset替换?
andrybak 2015年

2
@andrybak,它们确实防止$cyan$reset被替换,但是PS1每次打印提示时都会对其进行评估。您可以通过尝试PS1='$var> '然后提供var各种值来查看此信息,并查看提示如何更改。然后尝试PS1="$var> " 并注意提示保持静态;$var在分配过程中得到扩展,而不是每次PS1都进行评估。
盖尔哈,2015年

1
这真太了不起了。非常感谢您发布此信息!它使转义方括号变得更容易且更易读。
phyatt 2015年

我如何做这项工作PS1=${PS1}"\e]2;$@\a"。我尝试过PS1=${PS1}"\[\e]2;\]$@\[\a\]"
Ramana Reddy,

59

我想您已经PS1用颜色配置了,对吗?

只要确保您\[PS1报价内有报价,

例如:

PS1='\[\e[0;32m\u@\w/:\[\e[m '

我的PS1是export PS1='^[[96m'$(hostname)'<^[[92m${PWD}^[[96m>^[[97m '-我已经使用了很长时间了-它与KSH兼容...
BrianH

2
哇。我从一开始就一直使用终端提示,以前从未遇到过此问题。从来没有想过。谢谢。
bchurchill

3
在使用简单引号的同时使用\ [会产生意外的斜杠。同样,应该在魔术字符的末尾使用],如最佳投票答案中所述
igorsantos07

2
-1不起作用。您需要包装与非印刷部分\[的开始和\]结尾。
wjandrea

@ igorsantos07中的双反斜杠\\[是由编辑引起的错字。我已经解决了。
wjandrea

11

我遇到了类似的问题,终于找到了一个简单的解决方案。

.bashrc文件中添加以下行:

COLUMNS=250

然后键入source ~/.bashrc以获得所需的效果。


在某些情况下,例如狭窄的终止子细分,问题不在于提示色字符,而在于错误的COLUMNS值。这个答案使我摆脱了一个非常麻烦的漏洞!
卡莱斯·萨拉

1
无需注销。做source .bashrc。你的提示会立即更新
谢尔盖Kolodyazhnyy

1
我发现由于没有setwinsize为我的bash设置购物

1
我确实export COLUMNS=250紧随其后export TERM=xterm,这很高兴。
菲利普·基恩斯

5

即使我在\[\]分隔符中包含了颜色代码,我对自定义的彩色提示也遇到了同样的问题。事实证明,bash在从函数内部回显颜色方面存在问题。我最终只是在提示中使用变量,尽管我的.bashrc不太优雅,但现在一切正常。


如果仍然有人在阅读本文,则实际上可以在函数中转义颜色。请参阅链接问题上的此答案
wjandrea

3

一个简单的事情是在设置PS1之前添加以下行:

stty columns 1000

例如,

stty columns 1000
PS1='\[\e[0;32m\u@\w/:[\e[m '

但这确实会影响其他unix命令,例如ls和man。


1
在OSX中有效。
raskhadafi 2014年

4
这也会严重影响vim。请不要使用它。
justhalf

0

在tmux中连接时出现了这个问题。问题是我ipython在后台(ctrl + z)进行了会话,并且以某种方式中断了换行。当我结束它(fgctrl+d+d)我的终端开始正常工作

因此,请检查是否有任何停止的交互式提示。


0

所以我只是遇到了同样的问题,只是略有改动,我想我也将分享我的解决方案,只是增加一点点细微差别:D

我最初的PS1是

PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$"

我遇到的问题是我试图更改终端标题以及命令提示符。我这样做的方法是添加\[\033]0;\]Title\aPS1变量中。

所以现在我的PS1是:

PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$\[\033]0;\]Title\a"

这给我搞砸了换行。我终于发现,bash似乎不喜欢\a最后。为了避免这种情况,我将标题放在一个变量中,该变量似乎可以解决该问题。

TITLE="\033]0;Title\a"
PS1="\[\033[01;32m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$\[$TITLE\]"

0

\[\]没有为我工作。我想我是如何(从外部程序)生成提示的,或者是因为我的提示是“动态的”,有些不同。

经过阅读本我发现,你其实可以逃脱与颜色代码0x010x02字节。

例如,我使用的是Chalk的特殊版本,我使用以下方法包装颜色:

const Chalk = require('@nasc/chalk');

const chalk = new Chalk.constructor({
  wrapper: {
    pre: '\1',
    post: '\2',
  }
});
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.