I am trying to set PS1
so that it prints out something just right after login, but preceded with a newline later.
Suppose export PS1="\h:\W \u\$ "
, so first time (i.e., right after login) you get:
hostname:~ username$
I’ve been trying something like in my ~/.bashrc
:
function __ps1_newline_login {
if [[ -n "${PS1_NEWLINE_LOGIN-}" ]]; then
PS1_NEWLINE_LOGIN=true
else
printf '\n'
fi
}
export PS1="\$(__ps1_newline_login)\h:\W \u\$ “
expecting to get:
# <empty line>
hostname:~ username$
A complete example from the the beginning would be:
hostname:~ username$ ls `# notice: no empty line desired above!`
Desktop Documents
hostname:~ username$
Try the following:
function __ps1_newline_login {
if [[ -z "${PS1_NEWLINE_LOGIN}" ]]; then
PS1_NEWLINE_LOGIN=true
else
printf '\n'
fi
}
PROMPT_COMMAND='__ps1_newline_login'
export PS1="\h:\W \u\$ "
Explanation:
PROMPT_COMMAND
is a special bash variable which is executed every time before the prompt is set.- You need to use the
-z
flag to check if the length of a string is 0.
Running with dogbane's answer, you can make PROMPT_COMMAND "self-destruct", preventing the need to run a function after every command.
In your .bashrc
or .bash_profile
file, do
export PS1='\h:\W \u\$ '
reset_prompt () {
PS1='\n\h:\W \u\$ '
}
PROMPT_COMMAND='(( PROMPT_CTR-- < 0 )) && {
unset PROMPT_COMMAND PROMPT_CTR
reset_prompt
}'
When the file is processed, PS1
initially does not display a new-line before the prompt.
However, PROMPT_CTR
is immediately decremented to -1 (it is implicitly 0 before) before the prompt is shown the first time. After the first command, PROMPT_COMMAND
clears itself and the counter before resetting the prompt to include the new-line. Subsequently, no PROMPT_COMMAND
will execute.
Of course, there is a happy medium, where instead of PROMPT_COMMAND
clearing itself, it just resets to a more ordinary function. Something like
export PS1='\h:\W \u\$ '
normal_prompt_cmd () {
...
}
reset_prompt () {
PS1='\n\h:\W \u\$ '
}
PROMPT_COMMAND='(( PROMPT_CTR-- < 0 )) && {
PROMPT_COMMAND=normal_prompt_cmd
reset_prompt
unset PROMPT_CTR
}'
2018 Update (inspired by chepner's answer)
UPDATE: Fixed PROMPT_COMMAND
issues caused by other answers
Changes:
- No need to export PS1
- I used "\n$PS1" instead of re-typing.
- Other answers interfere with the
PROMPT_COMMAND
's default behavior (more info below)
Enter the following in ~/.bash_profile (substituting first line with your prompt):
PS1=YOUR_PROMPT_HERE
add_newline_to_prompt() {
is_new_login="true"
INIT_PROMPT_COMMAND="$PROMPT_COMMAND"
DEFAULT_PROMPT_COMMAND=update_terminal_cwd
PROMPT_COMMAND='{
if [ $is_new_login = "true" ]; then
is_new_login="false"
eval $INIT_PROMPT_COMMAND
else
PS1="\n$PS1"
PROMPT_COMMAND=$DEFAULT_PROMPT_COMMAND
fi
}'
}
add_newline_to_prompt
PROMPT_COMMAND
I noticed that my tab name in terminal wasn't updating to my current working directory and did some investigating. I realized that above solutions are messing with PROMPT_COMMAND
. Try this out:
- Comment out any modifications to
PROMPT_COMMAND
in your config files (.bash_profile etc.) - Add
INIT_PROMPT_COMMAND="$PROMPT_COMMAND"
to your config file
Now open a new shell:
$ echo $INIT_PROMPT_COMMAND
shell_session_history_check; update_terminal_cwd
$ echo $PROMPT_COMMAND
update_terminal_cwd
Notice that when you open a new shell, it runs both a "history check" and updates the name of the tab current working directory. Notice that it only runs the "history check" initially, and then never runs it again.
NOTE: I've only tested this on Mac's Terminal. May be different on other systems.
来源:https://stackoverflow.com/questions/14859148/how-to-set-a-conditional-newline-in-ps1