I have a situation where I need to provide a subshell to a user mid-way through a longish process. I would like to change the prompt to remind the user that they are in a special subshell and haven't gone through the rest of the process yet. I thought that this would do what I want...

echo "PS1='foo:'" | bash -i

But when I enter that line, this is the output I get

me@mercury:~$ PS1='foo:'

Is there a simple way around this? I could writeup my own custom bashrc... but I'd prefer to preserve the user's usual bash-shell setup.


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
if [ -f ~/.bashrc ]; then
    source ~/.bashrc

And then call with /bin/bash -rcfile ~/.bashrc.appsubshell -i

  • The usecase is pretty simple... the utility does a fairly complex transformation on a vendor's code repo, importing it to a local mercurial repo. Prints a bunch of status details out (like how many roots/heads/branches the resulting repo has), and then launches a shell to let the user investigate further. When they finish, the script asks if it should continue with the "difficult to undo" parts of the process. (In summary... privs aren't an issue here, but I want to make the users as comfortable with their own settings as possible) – user455 Feb 3 '11 at 1:08
  • In my case I was invoking a bash shell from inside a Ruby Rake task with the sh command, so this was the best solution by far. – Dave May 8 '15 at 16:13
  • With --rcfile you can do something like <(cat ~/.bashrc; echo 'PS1=foo'), whereas using --norc, you don't capture functions defined in bashrc (env vars should be in bash_profile, not bashrc). functions aren't in the environment, they need to be redefined in subshells. Of course --rc <(...) is just an inline version of the prefabricated rc. – Barry Kelly Oct 13 '20 at 14:35
  • The most practical effect of not sourcing ~/.bashrc is not including completion. – Barry Kelly Oct 13 '20 at 14:36

If you still want the ~/.bashrc to be read and assuming the ~/.bashrc does not set $PROMPT_COMMAND, you could use this trick:

  • I must assume that PROMPT_COMMAND is set. – bukzor Jan 1 '15 at 2:38
  • In my opinion, this is the best answer since you don't mess up with the subshell environment. – ivarec Mar 9 '16 at 18:00

After reading this page, here's how I ended up doing it.

In .bashrc:

# use prompt postfix
if [[ -n "$PROMPT_POSTFIX" ]]; then

Then, in the script I'm running the interactive shell from:

env PROMPT_POSTFIX="(whatever) " bash -i

The problem with using --norc is that it doesn't pull in your .bashrc file, so your interactive subshell won't have things you're used to using in Bash, like your history commands, etc. This way you can set PROMPT_POSTFIX whenever you call Bash and it will get added on to the prompt.


Agree with SiegeX (who beat me to it :))

To explain the behaviour:

Bash will only start in interactive mode if its std in and out are normal terminals. That's not the case when piping in that initial command.

You can use the -c option to provide commands, but that also precludes interactive mode.

If you really want to preserve user rc, simply add some test/source statements in the rcfile string to source ~/.bashrc and /etc/bashrc if the files exist.


I'm launching a subshell from a script so I can't just preserve the current environment, but I want the user to have their environment setup anyway.

I don't want to require stuff in the user's bashrc which I cannot control.

So what I did is source their bashrc, throw out PROMPT_COMMAND if it exists, and then set the PS1.

bash --rcfile <(echo ". ~/.bashrc; unset PROMPT_COMMAND; PS1='foo shell > '") -i

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.