Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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:'
foo:exit
me@mercury:~$ 

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.

share|improve this question

5 Answers 5

up vote 6 down vote accepted

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
share|improve this answer

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
share|improve this answer

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

In .bashrc:

# use prompt postfix
if [[ -n "$PROMPT_POSTFIX" ]]; then
    PS1="${PS1}${PROMPT_POSTFIX}"
fi

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.

share|improve this answer

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

share|improve this answer
    
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

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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