【问题标题】:bash command line can not read command properlybash 命令行无法正确读取命令
【发布时间】:2014-03-03 03:28:31
【问题描述】:

我有一个关于 bash 终端的问题,这让我发疯了,我不知道为什么。
这是关于终端的,让我描述如下:
一开始提示是这样的:

[12:00]ruan:~>  

但是当我连续输入字符时(例如,假设我输入了很多A),奇怪的事情发生了:

AAA:00]ruan:~ > AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA  

如您所见,我输入的字符从行首开始,这使我的命令无法读取。我不知道这怎么会发生。是和stty、inputrc还是别的有关?
/br

我的 tty 配置如下:

:)[11:38]ruan:~ > stty -a
speed 38400 baud; 25 rows; 80 columns;
lflags: icanon isig iexten echo echoe echok echoke -echonl echoctl
    -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
    -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
    -ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
    -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
    eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
    min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
    stop = ^S; susp = ^Z; time = 0; werase = ^W;

我已经设置了 PS1,例如:

NORMAL="\033[0m"
RED="\033[0;31m"
RED_BOLD="\033[1;31m"
GREEN="\033[0;32m"
GREEN_BOLD="\033[1;32m"
YELLOW="\033[0;33m"
YELLOW_BOLD="\033[1;33m"
BLUE="\033[0;34m"
BLUE_BOLD="\033[1;34m"
MAGENTA="\033[0;35m"
MAGENTA_BOLD="\033[1;35m"
CYAN="\033[0;36m"
CYAN_BOLD="\033[1;36m"

function smile_or_frown() {
    [[ $? = 0 ]] && echo -e "${CYAN_BOLD}:)" || echo -e "${MAGENTA_BOLD}:("
}
export PS1="\$(smile_or_frown)$BLUE_BOLD[\A]$GREEN_BOLD\u:$RED_BOLD\w$YELLOW_BOLD\$(parse_git_branch)$NORMAL > "

【问题讨论】:

  • 您是否尝试在其他客户端中重现该问题?
  • @d3c0y,是的,我第一次在办公室发现它,我想也许有人搞砸了环境。但是当我决定使用 bash 而不是 zsh 时,我发现它也存在于我家的 Mac 上。顺便说一句,我使用zsh时没有这种现象。
  • 什么是PS1(命令提示符),设置为?
  • @Leffler,请看我的编辑更新,我刚刚放好了

标签: linux bash terminal console tty


【解决方案1】:

您必须将所有 ANSI 转义序列包含在 \[ .. \] 中,以向 Bash 发出信号,表明这些转义序列不会占用终端上的空间。

它们必须在格式字符串本身中,并且不能是在提示时展开的数据的一部分(但可以在分配时展开的数据中)。

例如:

export PS1="\[$BLUE_BOLD\][\A]\[$GREEN_BOLD\]\u:\[$RED_BOLD\]\w\[$YELLOW_BOLD\]\$(parse_git_branch)\[$NORMAL\] > "

要使这个对smile_or_frown 起作用,你必须将它重构为两个函数,一个用于颜色,一个用于文本,这样你就可以做到"\[\$(smile_color)\]\$(smile_type)"

【讨论】:

  • “不能成为扩展数据的一部分”有点误导。他们可能是$BLUE_BOLD 和朋友的一部分,但不是\$(smile_color) 的一部分。但我也想不出一个简单的方法来解释这种差异。
  • 不一定所有转义序列都需要包含在\[/']'中;只是那些在命令行上不占用任何空间的。这告诉bash,尽管字符存在于PS1 中,但它们在终端中实际显示的字符串中不可见。
  • 谢谢你们,你们是对的。但我还有一些不清楚的地方。在我的问题中,在函数“smile_or_frown”中,如果我只使用“echo”而不是“echo -e”,结果将是:“[\e[1;36m]:)[10:12]eruahao@ eselnts1171:~",颜色好像没解释。为什么我不能将颜色信息放在函数输出中。当 $(smile_or_frown) 展开时,我认为它们都是一样的,但实际上并非如此。
  • @ruanhao in "\$(cmd)",cmd的输出被当作数据,而不是代码。这就像在例如ruby 其中var="1+2"; print var 不打印3,因为var 的内容被视为数据而不是代码。
  • @thatotherguy,被视为代码?我不明白这个。当 bash 准备好显示命令提示符时,我认为它应该像“eval PS1”。所以我想无论是从函数输出还是从字面上写出来,结果应该是一样的。我是不是哪里错了?
【解决方案2】:

运行此命令检查当前终端列(宽度)

tput cols

并使用它来将其设置为 80 列:

stty cols 80

编辑:根据您编辑的问题,您的复杂PS1 似乎是造成这种情况的原因。您可以将 PS1 重置为简单的:

PS1='$>'

也解决这个问题。

【讨论】:

  • like:)[11:38]ruan:~ > tput cols 80
  • 尝试设置PS1='$&gt;'
  • 是的,PS1=$> 有效,我的自定义有什么问题吗?
  • 这些转义码因终端类型而异,所以我不确定是哪一个引起了问题。
猜你喜欢
  • 2020-05-24
  • 1970-01-01
  • 2023-01-31
  • 1970-01-01
  • 2013-10-18
  • 2021-08-30
  • 2014-01-18
  • 1970-01-01
  • 2015-05-16
相关资源
最近更新 更多