How to invoke bash, run commands inside the new shell, and then give control back to user?

bash --rcfile <(echo '. ~/.bashrc; some_command')

dispenses the creation of temporary files. Question on other sites:

  • https://serverfault.com/questions/368054/run-an-interactive-bash-subshell-with-initial-commands-without-returning-to-the
  • https://unix.stackexchange.com/questions/123103/how-to-keep-bash-running-after-command-execution

This is a late answer, but I had the exact same problem and Google sent me to this page, so for completeness here is how I got around the problem.

As far as I can tell, bash does not have an option to do what the original poster wanted to do. The -c option will always return after the commands have been executed.

Broken solution: The simplest and obvious attempt around this is:

bash -c 'XXXX ; bash'

This partly works (albeit with an extra sub-shell layer). However, the problem is that while a sub-shell will inherit the exported environment variables, aliases and functions are not inherited. So this might work for some things but isn't a general solution.

Better: The way around this is to dynamically create a startup file and call bash with this new initialization file, making sure that your new init file calls your regular ~/.bashrc if necessary.

# Create a temporary file
TMPFILE=$(mktemp)

# Add stuff to the temporary file
echo "source ~/.bashrc" > $TMPFILE
echo "<other commands>" >> $TMPFILE
echo "rm -f $TMPFILE" >> $TMPFILE

# Start the new bash shell 
bash --rcfile $TMPFILE

The nice thing is that the temporary init file will delete itself as soon as it is used, reducing the risk that it is not cleaned up correctly.

Note: I'm not sure if /etc/bashrc is usually called as part of a normal non-login shell. If so you might want to source /etc/bashrc as well as your ~/.bashrc.


You can pass --rcfile to Bash to cause it to read a file of your choice. This file will be read instead of your .bashrc. (If that's a problem, source ~/.bashrc from the other script.)

Edit: So a function to start a new shell with the stuff from ~/.more.sh would look something like:

more() { bash --rcfile ~/.more.sh ; }

... and in .more.sh you would have the commands you want to execute when the shell starts. (I suppose it would be elegant to avoid a separate startup file -- you cannot use standard input because then the shell will not be interactive, but you could create a startup file from a here document in a temporary location, then read it.)

Tags:

Shell

Bash