Linux 带有最后退出代码的 Bash 提示
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16715103/
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
Bash Prompt with Last Exit Code
提问by feralin
So, I've been trying to customize by bash prompt so that it will look like
所以,我一直在尝试通过 bash 提示进行自定义,使其看起来像
[feralin@localhost ~]$ _
with colors. I managed to get constant colors (the same colors every time I see the prompt) but I want the username ('feralin') to appear red, instead of green, if the last command had a nonzero exit status. I came up with:
与颜色。我设法获得了恒定的颜色(每次看到提示时都是相同的颜色),但是如果最后一个命令的退出状态非零,我希望用户名('feralin')显示为红色,而不是绿色。我想出了:
\e[1;33m[$(if [[ $? == 0 ]]; then echo "\e[0;31m"; else echo "\e[0;32m"; fi)\u\e[m@\e[1;34m\h \e[0;35m\W\e[1;33m]$ \e[m
However, from my observations, the $(if ...; fi)
seems to be evaluated once, when the .bashrc
is run, and the result is substituted forever after. This makes the name always green, even if the last exit code is nonzero (as in, echo $?
). Is this what is happening? Or is it simply something else wrong with my prompt? Long question short, how do I get my prompt to use the last exit code?
但是,根据我的观察,$(if ...; fi)
似乎在.bashrc
运行时评估了一次,并且结果将永远被替换。这使得名称始终为绿色,即使最后一个退出代码非零(如,echo $?
)。这是正在发生的事情吗?或者只是我的提示有其他问题?长问题简短,如何让我提示使用最后一个退出代码?
采纳答案by demure
As you are starting to border on a complex PS1, you might consider using PROMPT_COMMAND
.
With this, you set it to a function, and it will be ran after each command to generate the prompt.
当您开始接近复杂的 PS1 时,您可能会考虑使用PROMPT_COMMAND
.
有了这个,你将它设置为一个函数,它将在每个命令之后运行以生成提示。
You could try the following in your ~/.bashrc
你可以在你的 ~/.bashrc
PROMPT_COMMAND=__prompt_command # Func to gen PS1 after CMDs
__prompt_command() {
local EXIT="$?" # This needs to be first
PS1=""
local RCol='\[\e[0m\]'
local Red='\[\e[0;31m\]'
local Gre='\[\e[0;32m\]'
local BYel='\[\e[1;33m\]'
local BBlu='\[\e[1;34m\]'
local Pur='\[\e[0;35m\]'
if [ $EXIT != 0 ]; then
PS1+="${Red}\u${RCol}" # Add red if exit code non 0
else
PS1+="${Gre}\u${RCol}"
fi
PS1+="${RCol}@${BBlu}\h ${Pur}\W${BYel}$ ${RCol}"
}
This should do what it sounds line you want.
Take a look a my bashrc's sub fileif you want to see all the things I do with my __prompt_command
function.
这应该按照您想要的方式进行。如果您想查看我使用我的函数所做的所有事情,请查看我的 bashrc 的子文件__prompt_command
。
回答by demure
Improved @demure
改进了@demure
I think this is important because there is not always exit status is 0 or 1.
我认为这很重要,因为退出状态并不总是 0 或 1。
if [ $EXIT != 0 ]; then
PS1+="${Red}${EXIT}:\u${RCol}" # Add red if exit code != 0
else
PS1+="${Gre}${EXIT}:\u${RCol}" # Also displays exit status
fi
回答by Velkan
I wanted to keep default Debian colors, print the exact code, and only print it on failure:
我想保留默认的 Debian 颜色,打印确切的代码,并且只在失败时打印它:
# Show exit status on failure.
PROMPT_COMMAND=__prompt_command
__prompt_command() {
local curr_exit="$?"
local BRed='\[\e[0;91m\]'
local RCol='\[\e[0m\]'
PS1='${debian_chroot:+($debian_chroot)}\[3[01;32m\]\u@\h\[3[00m\]:\[3[01;34m\]\w\[3[00m\]$ '
if [ "$curr_exit" != 0 ]; then
PS1="[${BRed}$curr_exit${RCol}]$PS1"
fi
}
回答by helios
If you don't want to use the prompt command there's two things you need to take into account:
如果您不想使用提示命令,则需要考虑两件事:
- getting the value of $? before anything else, otherwise it'll be overriden
- escaping all the $'s in the PS1 (so it's not evaluated when you assign it)
- 获得 $ 的价值?在其他任何事情之前,否则它将被覆盖
- 转义 PS1 中的所有 $(因此在分配时不会对其进行评估)
Working example using a variable
使用变量的工作示例
PS1="$(VALU="$?" ; echo $VALU ; date ; if [ $VALU == 0 ]; then echo zero; else echo nonzero; fi) "
Working example without a variable
没有变量的工作示例
Here the if needs to be the first thing, before any command that would override the $?
.
这里 if 需要是第一件事,在任何会覆盖$?
.
PS1="$(if [ $? == 0 ]; then echo zero; else echo nonzero; fi) "
Notice how the \$()
is escaped so it's not executed right away but each time PS1 is used. Also all the uses of \$?
请注意 是如何\$()
转义的,因此它不会立即执行,而是每次使用 PS1 时执行。还有所有的用途\$?
回答by Alexander Klimetschek
Compact solution:
紧凑的解决方案:
PS1='... $(code=${?##0};echo ${code:+[error: ${code}]})'
This approach does not require PROMPT_COMMAND
(apparently this can be slower sometimes) and prints [error: <code>]
if the exit code is non-zero, and nothing if it's zero:
这种方法不需要PROMPT_COMMAND
(显然这有时会更慢)并打印[error: <code>]
退出代码是否为非零,如果为零则不打印:
... > false
... [error: 1]> true
... >
Change the [error: ${code}]
part depending on your liking, with ${code}
being the non-zero code to print.
[error: ${code}]
根据您的喜好更改部分,${code}
作为要打印的非零代码。
Note the use of '
to ensure the inline $()
shell gets executed when PS1 is evaluated later, not when the shell is started.
请注意使用'
来确保在$()
稍后评估 PS1 时执行内联shell,而不是在启动 shell 时。
As bonus, you can make it colorful in red by adding \e[01;31m
in front and \e[00m
after to reset:
作为奖励,您可以通过\e[01;31m
在\e[00m
重置前后添加来使其变成红色:
PS1='... \e[01;31m$(code=${?##0};echo ${code:+[error: ${code}]})\e[00m'
--
——
How it works:
这个怎么运作:
- it uses bash parameter substitution
- first, the
${?##0}
will read the exit code$?
of the previous command - the
##
will remove any0
pattern from the beginning, effectively making a0
result an empty var (thanks @blaskoviczfor the trick) - we assign this to a temporary
code
variable as we need to do another substitution, and they can't be nested - the
${code:+REPLACEMENT}
will print theREPLACEMENT
part only if the variablecode
is set (non-empty) - this way we can add some text and brackets around it, and reference the variable again inline:
[error: ${code}]
- 它使用bash 参数替换
- 首先,
${?##0}
将读取$?
上一个命令的退出代码 - 在
##
将删除任何0
从一开始的模式,有效地使一个0
结果,一个空的VAR(感谢@blaskovicz用于特技) - 我们将它分配给一个临时
code
变量,因为我们需要进行另一个替换,并且它们不能嵌套 - 在
${code:+REPLACEMENT}
将打印REPLACEMENT
部分仅当该变量code
被设置(非空) - 这样我们就可以在它周围添加一些文本和括号,并再次内联引用该变量:
[error: ${code}]