How to expand PS1?

Since Bash 4.4 you can use the @P expansion:

First I put your prompt string in a variable myprompt using read -r and a quoted here-doc:

read -r myprompt <<'EOF'
${debian_chroot:+($debian_chroot)}\[\e[1;32m\]\u\[\e[0m\]@\[\e[1;32m\]\h\[\e[0m\]:\[\e[1;34m\]\w\[\e[0m\]$(__git_ps1 ' (%s)')$ 
EOF

To print the prompt (as it would be interpreted if it were PS1), use the expansion ${myprompt@P}:

$ printf '%s\n' "${myprompt@P}"
gniourf@rainbow:~$
$

(In fact there are some \001 and \002 characters, coming from \[ and \] that you can’t see in here, but you can see them if you try to edit this post; you’ll also see them in your terminal if you type the commands).


To get rid of these, the trick sent by Dennis Williamson on the bash mailing list is to use read -e -p so that these characters get interpreted by the readline library:

read -e -p "${myprompt@P}"

This will prompt the user, with the myprompt correctly interpreted.

To this post, Greg Wooledge answered that you might as well just strip the \001 and \002 from the string. This can be achieved like so:

myprompt=${myprompt@P}
printf '%s\n' "${myprompt//[$'\001'$'\002']}"

To this post, Chet Ramey answered that you could also turn off line editing altogether with set +o emacs +o vi. So this will do too:

( set +o emacs +o vi; printf '%s\n' "${myprompt@P}" )

Leave a Comment