views:

167

answers:

3

Hi, guys!

I have written cpp aplication called MyShell that takes as the params some real shell name (generally bash) and its params. MyShell works as a wrapper for it.

I need to change command prompting for the inner shell, specifically the PS1 environmental variable.

I know how to do it command-line way using PS1 env var:

$ PS1="[myshell]"$PS1

[myshell]$ 

But it is not so easy to do that from cpp application:

string newPS1 = "[myshell]" + string(getenv("PS1"));
setenv("PS1", newPS1.c_str());
if (execvp(shell, argv) < 0) {
    cerr << "can not exec " << shell << ": " << strerror(errno) << endl;
    exit(1);
}

afaik, when bash is invoked it executes command from /etc/.bashrc or /etc/profile (depending on users options). Those scipts redefine PS1 var too. So my

setenv("PS1", newPS1.c_str());

has no effect.

Any suggestion?

+1  A: 

If you want to change only prompt from default settings, you can append export PS1="[myshell]"$PS1 to ~/.bashrc or ~/.profile from your cpp application before launching your shell and suppress it after completion.

EDIT

If you don't want to alter original ~/.bashrc file you can invoque:

bash --rcfile /tmp/myCustomPS1

with /tmp/myCustomPS1 containing:

if [ -f ~/.bashrc ]
then
    . ~/.bashrc
fi
export PS1="[myshell]"$PS1
mouviciel
By hypothesis we don't have an access to edit these files.
Nelly
A: 

You can stop bash reading the .bahsrc files by using the command --norc and the profiles by --noprofile

e.g.

bash --noprofile --norc
Mark
But how's about users option?For example he writes $myshell bash -rcfile userRC \nAnd we'll silently ignore 'userRC'? Not good decision..
Nelly
Ah you give more information now but anything in userRC setting $PS1 will overwrite you value so I suspect this is the only way
Mark
+1  A: 

Once the sub process (child) of bash is invoked, it's free to do with its environment what ever it wants. This includes replacing your values for PS1 with something else. After all, it's just an environment variable.

The parent process cannot force the child process to keep certain environment variables. The parent process can pass certain environment variables, but that's it.

You can do other things with PROMPT_COMMAND and so on, but all of these can be overridden by the child process.

If you want the child process to enforce certain behavior with respect to environment variables, you'll have to modify that program to add the behavior you want.

Then you'll have your own custom prompt. Probably even should roll whatever else you do in MyShell into this and be done with it.

SuperMagic