bash: execute command given in commandline and don't exit

13

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?

marvin2k

Posted 2011-10-08T22:29:19.517

Reputation: 231

Answers

4

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:

[profiles]
[[default]]
    use_custom_command = True
    custom_command = "bash --rcfile <(cat ${HOME}/.bashrc; echo 'export PROMPT_COMMAND="vim; export PROMPT_COMMAND="') -i"

wor

Posted 2011-10-08T22:29:19.517

Reputation: 141

Thanks a lot. I prefer unset PROMPT_COMMAND rather than export PROMPT_COMMAND=, though. – Peque – 2015-07-20T17:04:52.423

2

bash -c 'vim; exec bash'

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

Michael Hoffman

Posted 2011-10-08T22:29:19.517

Reputation: 387

1I 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 – 2015-05-22T17:13:17.477

Actual solution. Not ugly. +1 – Andrew – 2019-06-25T21:14:38.627

1hm 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 – 2011-10-08T22:46:33.123

2

(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.

user1686

Posted 2011-10-08T22:29:19.517

Reputation: 283 655

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 – 2011-10-08T23:19:42.603

0

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
"

masher

Posted 2011-10-08T22:29:19.517

Reputation: 1

0

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.

klaus thorn

Posted 2011-10-08T22:29:19.517

Reputation: 5