Chinaunix首页 | 论坛 | 博客
  • 博客访问: 746102
  • 博文数量: 176
  • 博客积分: 2548
  • 博客等级: 少校
  • 技术积分: 1749
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-29 16:36
个人简介

爱咋咋地

文章分类

全部博文(176)

文章存档

2024年(1)

2023年(17)

2022年(19)

2021年(3)

2020年(1)

2018年(1)

2017年(1)

2014年(1)

2013年(4)

2012年(11)

2011年(19)

2010年(22)

2009年(71)

2008年(5)

分类: LINUX

2024-05-27 15:45:48

近来发现不知为何在shell的提示符的开头莫名其妙的多出了一个@。

一开始懒得管他,以为什么时候把PS1给改错了。今天看了一下PS1并没有错。这就很奇怪。
点击(此处)折叠或打开

  1. @[admin@fedora bash-5.2.21]$ echo $PS1
  2. [\u@\h \W]\$
  3. @[admin@fedora bash-5.2.21]$



在本地配置文件、国内互联网加外网一通翻找,愣是没有找到一丁点线索。这就很诡异。

运行bash -x也没有找到什么有用信息,这就很无奈。

还好可以代码加gdb,上网下载了对应版本的源代码,然后

点击(此处)折叠或打开

  1. export CFLAGS=“-g -O0"
  2. export LDFLAGS="-g -O0"
  3. configure && make

一遍过,不错不错。

不用安装,直接就对当前目录的bash进行gdb。


过程繁琐且无聊,无他,就是先从代码里面搜索prompt关键字,我找到的是y.tab.c文件

点击(此处)折叠或打开

  1. /* Issue a prompt, or prepare to issue a prompt when the next character
  2.    is read. */
  3. static void
  4. prompt_again (force)
  5.      int force;
  6. {


然后一个函数一个函数的深入,直到找到lib/readline/display.c的expand_prompt函数

点击(此处)折叠或打开

  1. /* Redraw the last line of a multi-line prompt that may possibly contain
  2.    terminal escape sequences. Called with the cursor at column 0 of the
  3.    line to draw the prompt on. */
  4. static void
  5. redraw_prompt (char *t)
  6. {
  7.   char *oldp;


  8.   oldp = rl_display_prompt;
  9.   rl_save_prompt ();


  10.   rl_display_prompt = t;
  11.   local_prompt = expand_prompt (t, PMT_MULTILINE, &prompt_visible_length, &prompt_last_invisible, &prompt_invis_chars_first_line, &prompt_physical_chars);



  1. /* Expand the prompt string S and return the number of visible

  2.    characters in *LP, if LP is not null. This is currently more-or-less

  3.    a placeholder for expansion. LIP, if non-null is a place to store the

  4.    index of the last invisible character in the returned string. NIFLP,

  5.    if non-zero, is a place to store the number of invisible characters in

  6.    the first prompt line. The previous are used as byte counts -- indexes

  7.    into a character buffer. *VLP gets the number of physical characters in

  8.    the expanded prompt (visible length) */



  9. /* Current implementation: \001 (^A) start non-visible characters \002 (^B) end non-visible characters all characters except \001 and \002 (following a \001) are copied to
  10.    the returned string; all characters except those between \001 and
  11.    \002 are assumed to be `visible'. */ /* Possible values for FLAGS: PMT_MULTILINE caller indicates that this is part of a multiline prompt */


  12. /* This approximates the number of lines the prompt will take when displayed */
  13. #define APPROX_DIV(n, d) (((n) < (d)) ? 1 : ((n) / (d)) + 1)


  14. static char *
  15. expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp)
  16. {
  17.   char *r, *ret, *p, *igstart, *nprompt, *ms;
  18.   int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
  19.   int mlen, newlines, newlines_guess, bound, can_add_invis;
  20.   int mb_cur_max;


  21.   /* We only expand the mode string for the last line of a multiline prompt
  22.      (a prompt with embedded newlines). */
  23.   ms = (((pmt == rl_prompt) ^ (flags & PMT_MULTILINE)) && _rl_show_mode_in_prompt) ? prompt_modestr (&mlen) : 0;
  24.   if (ms)
  25.     {


根据gdb和上面的函数调用可以确定:前两个条件(pmt == rl_prompt) 和 (flags & PMT_MULTILINE)都为真,其决定作用的是_rl_show_mode_in_prompt开关项。


去代码中搜索这一项可以看到在lib/readline/bind.c文件中的信息:

点击(此处)折叠或打开

  1. { "show-all-if-unmodified", &_rl_complete_show_unmodified, 0 },
  2. { "show-mode-in-prompt", &_rl_show_mode_in_prompt, 0 },
  3. { "skip-completed-text", &_rl_skip_completed_text, 0 },


再去网上搜show-mode-in-prompt,发现是inputrc(vi ~/.inputrc)里面的一个选项。应该是前段时间玩vi mode的bash shell时打开的。

点击(此处)折叠或打开

  1. #set show-mode-in-prompt on

也就是说:开头的@应该叫做“模式提示符”


关掉后一切OK。

点击(此处)折叠或打开

  1. [admin@fedora bash-5.2.21]$ echo $PS1
  2. [\u@\h \W]\$
  3. [admin@fedora bash-5.2.21]$


遇事不决,源码解决,诚不我欺也!

阅读(110) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~