Reputation: 189
I'm working on a prompt customization, but for some reason, when I use the \u
, \h
and \W
variables as is it works perfectly, but when I put them inside a function, they are displayed as "\u" or "\W" instead of their values.
...
print_user()
{
echo -e "\001\u\002@\001\h\002"
}
print_dir()
{
echo -e "\001${YELLOW}\002\001\W\002\001${RESET_ATTR}\002"
}
PS1='[$(print_user) on $(print_dir)] $(get_git_repo) \001\n\002$(print_prompt) '
This displays as:
[\u@\h on \W]
>
If I move them outside of the function like so
PS1='[\[\u\]@\[\h\] \[${YELLOW}\]\[\w\]\[${RESET_ATTR}\]] $(get_git_repo) \[\n\]$(print_prompt)'
It works fine, and displays the current directory with the username and hostname:
[myusername@arch on ~]
>
Is this just how bash works? Is there a different way of doing it so it will work? Why is it that inside of a function it won't display the variables' values but outside of a function it does?
Upvotes: 1
Views: 635
Reputation: 530872
From the man page, under PROMPTING
Bash allows these prompt strings to be customized by inserting a number of backslash-escaped special characters that are decoded as follows:
[...]
After the string is decoded, it is expanded via parameter expansion, command substitution, arithmetic expansion, and quote removal, subject to the value of the promptvars shell option (see the description of the shopt command under SHELL BUILTIN COMMANDS below).
By the time the shell expands $(print_user)
to add \u
to the string, it is too late to decode it, so the literal string \u
remains in the prompt.
One alternative is to use PROMPT_COMMAND
to execute a function that defines PS1
dynamically, just before it is displayed, instead of embedding command substitution in the value of PS1
itself.
make_prompt () {
PS1="[$(print_user) on $(print_dir)] $(get_git_repo)"
PS1+='\[\n\]'
PS1+="$(print_prompt) "
}
PROMPT_COMMAND=make_prompt
Now, print_user
will have been called before the shell decodes the value of PS1
, by which time all the prompt escapes will be present.
Upvotes: 1