Changing the PS1 on an interactive bash subshell easily
You can use process substitution to essentially make a ~/.bashrc that only exists for the bash -i
invocation like so:
bash --rcfile <(echo "PS1='foo: '") -i
I think it would be better to use env PS1="foo: " /bin/bash --norc -i
instead of using the --rcfile
option. The environment is preserved, not overwritten by the dot files and the PS1 environment variable is set before entering the shell.
You might also want to think about opening a restricted shell, if the calling program gives extra privs. env PS1="foo: " PATH=$RESTRICTED_PATH /bin/rbash --norc -i
for whatever value you want for $RESTRICTED_PATH.
Or have an already prefabricated bashrc file:
if [ -f /etc/bashrc ]; then
source /etc/bashrc
fi
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
PS1="foo:"
PATH=$RESTRICTED_PATH
And then call with /bin/bash -rcfile ~/.bashrc.appsubshell -i
If you still want the ~/.bashrc
to be read and assuming the ~/.bashrc
does not set $PROMPT_COMMAND
, you could use this trick:
PROMPT_COMMAND='PS1="foo: ";unset PROMPT_COMMAND' bash
Another approach which would work even if your rc files set $PS1
and $PROMPT_COMMAND
would be to do (from a zsh/bash/ksh93 shell) something like this:
(
export IN_FD
exec {IN_FD}<&0
echo 'PS1="foo: "; exec <&"$IN_FD" {IN_FD}<&-' | bash -i
)
That is feed the PS1="foo: "
via a pipe and then tell bash
to switch stdin to the original stdin.
That has the side effect of displaying a prompt and that command line on stderr. You could work around it with:
(
export IN_FD ERR_FD
exec {IN_FD}<&0 {ERR_FD}>&2 2> /dev/null
echo 'PS1="foo: "; exec <&"$IN_FD" {IN_FD}<&- 2>&"$ERR_FD" {ERR_FD}>&-' |
bash -i
)
Though that has the side effect of hiding the error messages output by your startup files if any.