首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >PS1和PROMPT_COMMAND有什么区别?

PS1和PROMPT_COMMAND有什么区别?
EN

Stack Overflow用户
提问于 2010-06-17 09:27:30
回答 3查看 51.6K关注 0票数 134

在查看this awesome thread时,我注意到一些示例使用

代码语言:javascript
复制
PS1="Blah Blah Blah"

还有一些用法

代码语言:javascript
复制
PROMPT_COMMAND="Blah Blah Blah"

(有些人在Bash shell中设置提示符时两者都使用)。两者之间的区别是什么?Stack和Overflow搜索,甚至更广泛的谷歌搜索都不会给我带来结果,所以即使是指向正确位置的链接也会受到感谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-06-17 09:38:00

从GNU Bash文档页面(Bash Reference Manual):

代码语言:javascript
复制
PROMPT_COMMAND
    If set, the value is interpreted as a command to execute before
    the printing of each primary prompt ($PS1).

我从来没有用过它,但我可以在只有sh的时候使用它。

票数 68
EN

Stack Overflow用户

发布于 2010-06-17 09:45:48

PROMPT_COMMAND可以包含普通的Bash语句,而PS1变量也可以在变量中包含特殊字符,例如'\h‘代表主机名。

例如,下面是同时使用PROMPT_COMMAND和PS1的Bash提示符。PROMPT_COMMAND中的Bash代码计算出您可能在哪个Git分支中,并在提示符处显示它,以及上次运行进程的退出状态、pwd的主机名和基名。

变量RET存储最后执行的程序的返回值。这便于查看是否存在错误以及我在终端中运行的最后一个程序的错误代码。注意整个PROMPT_COMMAND表达式周围的‘外层’。它包含PS1,因此每次计算PROMPT_COMMAND变量时都会重新计算此变量。

代码语言:javascript
复制
PROMPT_COMMAND='RET=$?;\
  BRANCH="";\
  ERRMSG="";\
  if [[ $RET != 0 ]]; then\
    ERRMSG=" $RET";\
  fi;\
  if git branch &>/dev/null; then\
    BRANCH=$(git branch 2>/dev/null | grep \* |  cut -d " " -f 2);\
  fi;
PS1="$GREEN\u@\h $BLUE\W $CYAN$BRANCH$RED$ERRMSG \$ $LIGHT_GRAY";'

非Git目录中的示例输出如下所示:

代码语言:javascript
复制
sashan@dhcp-au-122 Documents  $ false
sashan@dhcp-au-122 Documents  1 $

在Git目录中,您可以看到分支名称:

代码语言:javascript
复制
sashan@dhcp-au-122 rework mybranch $

更新

在阅读了评论和Bob的答案后,我认为按照他的描述来写会更好。它比我最初编写的代码更易于维护,在上面的代码中,PS1变量是在PROMPT_COMMAND中设置的,它本身就是一个超级复杂的字符串,在运行时由Bash进行求值。

它是有效的,但它比需要的更复杂。公平地说,我在大约10年前为自己写了这个PROMPT_COMMAND,它工作得很好,并没有想太多。

对于那些好奇我是如何修改我的东西的人,我基本上已经将PROMPT_COMMAND的代码放在一个单独的文件中(正如Bob所描述的那样),然后回显我打算作为PS1的字符串:

代码语言:javascript
复制
GREEN="\[\033[0;32m\]"
CYAN="\[\033[0;36m\]"
RED="\[\033[0;31m\]"
PURPLE="\[\033[0;35m\]"
BROWN="\[\033[0;33m\]"
LIGHT_GRAY="\[\033[0;37m\]"
LIGHT_BLUE="\[\033[1;34m\]"
LIGHT_GREEN="\[\033[1;32m\]"
LIGHT_CYAN="\[\033[1;36m\]"
LIGHT_RED="\[\033[1;31m\]"
LIGHT_PURPLE="\[\033[1;35m\]"
YELLOW="\[\033[1;33m\]"
WHITE="\[\033[1;37m\]"
RESTORE="\[\033[0m\]" #0m restores to the terminal's default colour

if [ -z $SCHROOT_CHROOT_NAME ]; then
    SCHROOT_CHROOT_NAME=" "
fi
BRANCH=""
ERRMSG=""
RET=$1
if [[ $RET != 0 ]]; then
    ERRMSG=" $RET"
fi
if which git &>/dev/null; then
    BRANCH=$(git branch 2>/dev/null | grep \* |  cut -d " " -f 2)
else
    BRANCH="(git not installed)"
fi
echo "${GREEN}\u@\h${SCHROOT_CHROOT_NAME}${BLUE}\w \
${CYAN}${BRANCH}${RED}${ERRMSG} \$ $RESTORE"

在我的.bashrc文件中:

代码语言:javascript
复制
function prompt_command {
    RET=$?
    export PS1=$(~/.bash_prompt_command $RET)
}
PROMPT_DIRTRIM=3
export PROMPT_COMMAND=prompt_command
票数 74
EN

Stack Overflow用户

发布于 2012-06-20 02:57:49

不同之处在于,PS1是实际使用的提示符字符串,而PROMPT_COMMAND是在提示符之前执行的命令。如果您想要以最简单、最灵活的方式构建提示符,请尝试以下方法:

将以下内容放入您的.bashrc文件中:

代码语言:javascript
复制
function prompt_command {
  export PS1=$(~/bin/bash_prompt)
}
export PROMPT_COMMAND=prompt_command

然后编写一个脚本(Bash、PerlRuby:您可以选择),并将其放在文件~/bin/bash中。

脚本可以使用它喜欢的任何信息来构造提示符。IMO,这要简单得多,因为您不需要学习专门为PS1变量开发的巴洛克式的替代语言。

您可能认为,只需将PROMPT_COMMAND直接设置为~/bin/bash,并将PS1设置为空字符串,就可以完成同样的操作。

乍一看,这似乎是可行的,但您很快就会发现,readline代码期望将PS1设置为实际的提示符,当您向后滚动历史记录时,结果就变得混乱了。

此解决方法会使PS1始终反映最新的提示(因为该函数设置了调用shell的实例所使用的实际PS1变量),这使得readline和命令历史记录可以正常工作。

票数 47
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3058325

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档