how do I specifiy a command on the commmandline of bash which shall be executed once inside the new bash after reading ~/.bashrc -- But all this without letting bash exit after the command is finished?

I'm fiddling around with a "boot-up-configuration" for terminator where some splits should start some applications (vim, mutt, irrsi) after startup. But I still want normal shells in the background (ctrl-z and so on...) so after quitting an application I have the same shell which I had during the eapplications lifetime...

What does not work for me (based on given answers)

 ( bash; vim )              # vim waits for the exit of bash...
 bash -c vim                # bash exits after vims exit...
 bash -c 'vim; exec bash'   # bash is executed _after_ vim... ctrl-z won't work
 echo vim | bash -s         # "Vim: Warning: Input is not from a terminal"     

Manually appending "vim" to a temporary bashrc does not work either. vim starts up correctly, but there is still no background bash present where a ctrl-z would bring me to.

Any suggestions?

5 Answers 5

bash -c 'vim; exec bash'

The exec bash will replace the current Bash instance with a new one.

  • 1
    hm yeah... this solves the "empty split after exit" issue... but ctrl-z still does not work -- bash is simply executed again after vims exit... I need vim inside bash
    – marvin2k
    Oct 8, 2011 at 22:46
  • 1
    I have been using this form and just noticed that it doesn't inherit aliases etc when using just exec bash. exec bash --login helps but as noted this runs bash inside bash which isn't really quite what we want.
    – altendky
    May 22, 2015 at 17:13
  • Actual solution. Not ugly. +1
    – Andrew
    Jun 25, 2019 at 21:14
  • This is so simple. 💯 Apr 9, 2021 at 15:44

I seem to have found a way to solve this so that the job control works:

bash --rcfile <(cat ${HOME}/.bashrc; echo 'export PROMPT_COMMAND="vim; export PROMPT_COMMAND="') -i

This creates custom bashrc file on the fly and uses PROMPT_COMMAND variable to delay the Vim start so that job control should work. This of course can be generalized to not be Vim specific.

Ok, just tested this with terminator and at least seems to work with config file:

    use_custom_command = True
    custom_command = "bash --rcfile <(cat ${HOME}/.bashrc; echo 'export PROMPT_COMMAND="vim; export PROMPT_COMMAND="') -i"
  • Thanks a lot. I prefer unset PROMPT_COMMAND rather than export PROMPT_COMMAND=, though.
    – Peque
    Jul 20, 2015 at 17:04

(Ab)using .bashrc is the only usable way.1 Generation is unnecessary, however – just put the command(s) in an environment variable and eval it:

  • Put the following at the end of your ~/.bashrc:

    [[ $startup_cmd ]] && {
        declare +x startup_cmd
        eval "$startup_cmd"
  • Configure Terminator to start this command:

    env startup_cmd='vim' bash

1 Let's exclude the "use C4 to crack a nut" ones.

  • looks nice and works at the first glance... have to modify bashrc, could life with that... but for whatever reason, ctrl-z still does not work -- any idea? -- in what sort of cupboard would I find the c4-based solution?
    – marvin2k
    Oct 8, 2011 at 23:19

I had this same problem in the context of wanting to spawn vim in a tmux window with the ability to ctrl-z out. In the end, I failed to figure out how to do it cleanly inside of bash. I settled on the following:

tmux new-session -d -s foo
tmux send-keys -t foo:0.0 "vim
bash --rcfile <(cat ${HOME}/.bashrc; echo 'trap vim 12'; echo 'echo $$>/tmp/foo'; echo '( sleep 1;kill -12 `</tmp/foo`; )' ) -i

Thanks to user wor for the "custom bashrc file on the fly"!

The other crucial part is "trap", a bash-builtin:

  • The trap command above just defines vim to be executed if the bash receives signal 12.
  • Put into background during rcfile execution, a lurking kill -12 command waits one second so that bash can finish initializing. If you omit this, a Ctrl-Z during vim would not put you into a working shell.
  • Then kill is executed and thus vim is started.
  • kill reads the process id from /tmp/foo. There probably is a more elegant way.
  • I also tested Ctrl-Z and it works as expected.

I have no idea what the "terminator" which you mention is, by the way.

I found this while searching for a solution with bash and screen.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .