bash PS1 和 PROMPT_COMMAND 有什么区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3058325/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the difference between PS1 and PROMPT_COMMAND
提问by Jed Daniels
While taking a look at this awesome threadI noticed that some examples use
在查看这个很棒的线程时,我注意到一些示例使用
PS1="Blah Blah Blah"
and some use
和一些使用
PROMPT_COMMAND="Blah Blah Blah"
(and some use both) when setting the prompt in a bash shell. What is the difference between the two? An SO search and even a bit of broader google searching aren't getting me results, so even a link to the right place to look for the answer would be appreciated.
(有些人同时使用)在 bash shell 中设置提示时。两者有什么区别?SO 搜索,甚至更广泛的谷歌搜索都没有得到我的结果,所以即使是指向正确位置的链接来寻找答案也将不胜感激。
采纳答案by Scott Thomson
From the GNU Bash doc page: http://www.gnu.org/software/bash/manual/bashref.html
来自 GNU Bash 文档页面:http: //www.gnu.org/software/bash/manual/bashref.html
PROMPT_COMMAND
If set, the value is interpreted as a command to execute before
the printing of each primary prompt ($PS1).
I never used it, but I could have used this back when I only had sh.
我从未使用过它,但是当我只有 sh 时我可以使用它。
回答by sashang
PROMPT_COMMAND can contain ordinary bash statements whereas the PS1 variable can also contain the special characters, such as '\h' for hostname, in the variable.
PROMPT_COMMAND 可以包含普通的 bash 语句,而 PS1 变量也可以在变量中包含特殊字符,例如 '\h' 表示主机名。
For example here is my bash prompt that uses both PROMPT_COMMAND and PS1. The bash code in PROMPT_COMMAND works out what git branch you might be in and displays that at the prompt, along with the exit status of the last run process, hostname and basename of the pwd. The variable RET stores the return value of the last executed program. This is convenient to see if there was an error and the error code of the last program I ran in the terminal. Note the outer ' surrounding the entire PROMPT_COMMAND expression. It includes PS1 so that this variable is re-evaluated each time the PROMPT_COMMAND variable is evaluated.
例如,这里是我的 bash 提示,它同时使用了 PROMPT_COMMAND 和 PS1。PROMPT_COMMAND 中的 bash 代码计算出您可能在哪个 git 分支,并在提示符处显示,以及上次运行进程的退出状态、主机名和密码的基本名称。变量 RET 存储最后执行的程序的返回值。这样方便查看是否有错误以及我在终端中运行的最后一个程序的错误代码。注意整个 PROMPT_COMMAND 表达式周围的外部 '。它包括 PS1,因此每次评估 PROMPT_COMMAND 变量时都会重新评估此变量。
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";'
Example output looks like this in a non-git directory:
示例输出在非 git 目录中如下所示:
sashan@dhcp-au-122 Documents $ false
sashan@dhcp-au-122 Documents 1 $
and in a git directory you see the branch name:
在 git 目录中,您会看到分支名称:
sashan@dhcp-au-122 rework mybranch $
Update
更新
After reading the comments and Bob's answer I think that writing it as he describes is better. It's more maintainable than what I originally wrote above, where the PS1 variable is set inside the PROMPT_COMMAND, which itself is a super complicated string that is evaluated at runtime by bash. It works, but it's more complicated than it needs to be. To be fair I wrote that PROMPT_COMMAND for myself about 10 years ago and it worked and didn't think too much about it.
阅读评论和鲍勃的回答后,我认为按照他的描述写更好。它比我上面最初写的更易于维护,其中 PS1 变量设置在 PROMPT_COMMAND 内部,它本身是一个超级复杂的字符串,在运行时由 bash 评估。它有效,但它比它需要的更复杂。公平地说,我在大约 10 年前为自己写了 PROMPT_COMMAND 并且它有效并且没有考虑太多。
For those curious as to how I've amended my things, I've basically put the code for the PROMPT_COMMAND in separate file (as Bob described) and then echo the string that I intend to be PS1:
对于那些对我如何修改我的东西感到好奇的人,我基本上将 PROMPT_COMMAND 的代码放在单独的文件中(如 Bob 所述),然后回显我打算成为 PS1 的字符串:
GREEN="\[3[0;32m\]"
CYAN="\[3[0;36m\]"
RED="\[3[0;31m\]"
PURPLE="\[3[0;35m\]"
BROWN="\[3[0;33m\]"
LIGHT_GRAY="\[3[0;37m\]"
LIGHT_BLUE="\[3[1;34m\]"
LIGHT_GREEN="\[3[1;32m\]"
LIGHT_CYAN="\[3[1;36m\]"
LIGHT_RED="\[3[1;31m\]"
LIGHT_PURPLE="\[3[1;35m\]"
YELLOW="\[3[1;33m\]"
WHITE="\[3[1;37m\]"
RESTORE="\[3[0m\]" #0m restores to the terminal's default colour
if [ -z $SCHROOT_CHROOT_NAME ]; then
SCHROOT_CHROOT_NAME=" "
fi
BRANCH=""
ERRMSG=""
RET=
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"
and in my .bashrc
在我的 .bashrc 中
function prompt_command {
RET=$?
export PS1=$(~/.bash_prompt_command $RET)
}
PROMPT_DIRTRIM=3
export PROMPT_COMMAND=prompt_command
回答by Bob
The difference is that PS1 is the actual prompt string used, and PROMPT_COMMAND is a command that is executed just before the prompt. If you want the simplest, most flexible way of building a prompt, try this:
不同之处在于 PS1 是实际使用的提示字符串,而 PROMPT_COMMAND 是在提示之前执行的命令。如果您想要构建提示的最简单、最灵活的方式,请尝试以下操作:
Put this in your .bashrc:
把它放在你的 .bashrc 中:
function prompt_command {
export PS1=$(~/bin/bash_prompt)
}
export PROMPT_COMMAND=prompt_command
Then write a script (bash, perl, ruby: your choice), and place it in ~/bin/bash_prompt.
然后编写一个脚本(bash、perl、ruby:你的选择),并将它放在 ~/bin/bash_prompt 中。
The script can use any information it likes to construct a prompt. This is much simpler IMO because you don't have to learn the somewhat baroque substitution language that was developed just for the PS1 variable.
脚本可以使用它喜欢的任何信息来构造提示。这在 IMO 中要简单得多,因为您不必学习专为 PS1 变量开发的有点巴洛克风格的替代语言。
You might think that you could do the same by simply setting PROMPT_COMMAND directly to ~/bin/bash_prompt, and setting PS1 to the empty string. This at first appears to work, but you soon discover that the readline code expects PS1 to be set to the actual prompt, and when you scroll backwords in history, things get messed up as a result. This workaround causes PS1 to always reflect the latest prompt (since the function sets the actual PS1 used by the invoking instance of the shell), and this makes readline and command history work fine.
您可能认为只需将 PROMPT_COMMAND 直接设置为 ~/bin/bash_prompt 并将 PS1 设置为空字符串即可完成相同的操作。这起初似乎有效,但您很快就会发现 readline 代码期望 PS1 设置为实际提示,而当您滚动历史记录中的倒叙时,结果会变得一团糟。此变通方法使 PS1 始终反映最新的提示(因为该函数设置调用 shell 实例使用的实际 PS1),这使得 readline 和命令历史记录正常工作。
回答by Cyker
From man bash
:
来自man bash
:
PROMPT_COMMAND
If set, the value is executed as a command prior to issuing each primary prompt.
PS1
The value of this parameter is expanded (see PROMPTING below) and used as the primary prompt string. The default value is ''\s-\v\$ ''.
PROMPT_COMMAND
如果设置,该值在发出每个主要提示之前作为命令执行。
PS1
此参数的值被扩展(参见下面的 PROMPTING)并用作主要提示字符串。默认值为''\s-\v\$''。
If you simply want to set the prompt string, using PS1
alone is enough:
如果你只是想设置提示字符串,PS1
单独使用就足够了:
PS1='user \u on host \h$ '
If you want to do something else just before printing the prompt, use PROMPT_COMMAND
. For example, if you want to sync cached writes to disk, you can write:
如果您想在打印提示之前执行其他操作,请使用PROMPT_COMMAND
. 例如,如果要将缓存写入同步到磁盘,则可以编写:
PROMPT_COMMAND='sync'
回答by pal
the difference is that
不同之处在于
- if you output incomplete line from
PROMPT_COMMAND
, it will screw your bash prompt PS1
substitutes\H
and friendsPROMPT_COMMAND
runs its contents,PS1
uses its contents as prompt.
- 如果您从 输出不完整的行
PROMPT_COMMAND
,它将破坏您的 bash 提示 PS1
替代品\H
和朋友PROMPT_COMMAND
运行其内容,PS1
将其内容用作提示。
PS1
does variable expansion and command substitution at each prompt, no need to use PROMPT_COMMAND
to assign value to PS1
or to run arbitrary code. you can easily do export PS1='$(uuidgen) $RANDOM'
once in .bash_profile
, just use single quotes
PS1
在每个提示符处进行变量扩展和命令替换,无需使用PROMPT_COMMAND
赋值PS1
或运行任意代码。你可以很容易地做export PS1='$(uuidgen) $RANDOM'
一次.bash_profile
,只需使用单引号
回答by Geoff Nixon
Yeah, so to try to really nail this down:
是的,所以要尝试真正确定这一点:
PROMPT_COMMAND
is a handy bashconvenience variable/function, but there is, strictly speaking, nothing that cannot also be done usingPS1
alone, correct?
PROMPT_COMMAND
是一个方便的bash便利变量/函数,但严格来说,没有什么不能PS1
单独使用的,对吗?
I mean, if one wants to setanothervariable with scope outside the prompt: depending on the shell, that variable would probably need to be declared first outside $PS1
or (worst case) one might have to get fancy with something waiting on a FIFO prior to calling $PS1
(and armed again at the end of $PS1
); the \u
\h
might cause some trouble, particularly if you're using some fancy regex; but otherwise: one can accomplish anything PROMPT_COMMAND
can by using command substitution within $PS1
(and, maybe in corner cases, explicit subshells)?
我的意思是,如果有人想在提示之外设置另一个具有作用域的变量:取决于 shell,该变量可能需要首先在外部声明,$PS1
或者(最坏的情况)可能需要在 FIFO 之前等待一些东西呼叫$PS1
(并在 结束时再次武装$PS1
);这\u
\h
可能会引起一些麻烦,特别是如果您使用一些花哨的正则表达式;但除此之外:PROMPT_COMMAND
通过在$PS1
(并且,也许在极端情况下,显式子shell)中使用命令替换可以完成任何事情?
Right?
对?