One of the advantages of open source software is that the source, well, is open :-)
If you download the code for bash (I'm looking at version 4.2), there is a y.tab.c file that contains the decode_prompt_string() function:
char *decode_prompt_string (string) char *string; { ... }
You can try to extract this (along with any necessary support routines and create an executable file that did the job for you). Although from a cursory attempt, these support routines seem to be many, so this can be a difficult task.
Other than that, you can probably fool bash to expand it for you with something like:
expPS1=$(echo xyzzyplughtwisty | bash -i 2>&1 | grep xyzzyplughtwisty | head -1 | sed 's/xyzzyplughtwisty//g')
Now I put it on several lines for readability, but it was done on one line.
In this case, an interactive instance of bash is executed, passing (which I hope) an invalid command.
Since it is interactive, it prints a prompt, so I take the first line with the command line and delete this command line. The rest should be an invitation.
On my system, this is what I get:
pax> expPS1=$(echo xyzzyplughtwisty | bash -i 2>&1 | grep xyzzyplughtwisty | head -1 | sed 's/xyzzyplughtwisty//g') pax> echo "[$expPS1]" [pax> ] pax>
However, this has problems with multi-line queries and will actually give you your regular invitation, not the current shell.
If you want to do it right, maybe this is a bit related to bash . Below are the steps to add an internal evalps1 .
First, change support/mkversion.sh so that you donโt confuse it with the โrealโ bash , and therefore FSF may deprive all knowledge for guarantee purposes :-) Just change one line (I added the <bit t212>):
echo "#define DISTVERSION \"${float_dist}-pax\""
Second, modify `builtins / Makefile.in to add a new source file. This entails several steps.
(a) Add $(srcdir)/evalps1.def to the end of DEFSRC .
(b) Add evalps1.o to the end of OFILES .
(c) Add the necessary dependencies:
evalps1.o: evalps1.def $(topdir)/bashtypes.h $(topdir)/config.h \ $(topdir)/bashintl.h $(topdir)/shell.h common.h
Thirdly, add the builtins/evalps1.def file builtins/evalps1.def , this is the code that runs when the evalps1 command is evalps1 :
This file is evalps1.def, from which is created evalps1.c. It implements the builtin "evalps1" in Bash. Copyright (C) 1987-2009 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. Bash is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Bash is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Bash. If not, see <http://www.gnu.org/licenses/>. $PRODUCES evalps1.c $BUILTIN evalps1 $FUNCTION evalps1_builtin $SHORT_DOC evalps1 Outputs the fully interpreted PS1 prompt. Outputs the PS1 prompt, fully evaluated, for whatever nefarious purposes you require. $END
Most of this is the GPL license (since I changed it with exit.def ) with a very simple function at the end to get and decode PS1 .
Finally, just create a thing in the top-level directory:
./configure make
The paxsh bash can be renamed to paxsh , although I doubt it will ever become as common as its ancestor paxsh
And by running it, you can see it in action:
pax> mv bash paxsh pax> ./paxsh --version GNU bash, version 4.2-pax.0(1)-release (i686-pc-linux-gnu) Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software; you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. pax> ./paxsh pax> echo $BASH_VERSION 4.2-pax.0(1)-release pax> echo "[$PS1]" [pax> ] pax> echo "[$(evalps1)]" [pax> ] pax> PS1="\h: " paxbox01: echo "[$PS1]" [\h: ] paxbox01: echo "[$(evalps1)]" [paxbox01: ]
Now, provided, making changes to the code in bash to add an internal command may be considered excessive, but if you want to get an accurate PS1 score, this is definitely an option.