37

For starting my dev environment I wrote a little script. One part is to open a gnome terminal with several tabs where automatically some commands should be executed. Some of those commands depend on an already executed .bashrc. But when using

gnome-terminal --tab -e "command" --tab --tab

the command is executed before .bashrc was executed. Is there a possibility to make an automated gnome-terminal -e behave like a manually used one? (even commands like "cd /foo/bar" do not work with gnome-terminal -e)

medihack
  • 900
  • 3
  • 12
  • 19

2 Answers2

50

Once gnome-terminal has started bash, it's out of the loop as far as command execution is concerned: it only manages the input and output. So you'll need bash's cooperation to run something after ~/.bashrc has been loaded.

First, in many cases, you don't actually need to execute commands after ~/.bashrc. For example, opening a terminal in a particular directory can simply be done with cd /foo/bar && gnome-terminal. You can set environment variables in a similar way: VAR=value gnome-terminal. (If your ~/.bashrc overrides environment variables, you're doing it wrong: environment variable definitions belong in ~/.profile)

To execute commands in the terminal, but before ~/.bashrc, you can do

gnome-terminal -x sh -c 'command1; command2; exec bash'

If you want to use multiple tabs, you have to use -e instead of -x. Gnome-terminal unhelpfully splits the argument of -e at spaces rather than executing it through a shell. Nonetheless, you can write a shell command if you make sure not to include spaces in it. At least with gnome-terminal 2.26, you can use tabs, though (replace <TAB> by a literal tab character):

gnome-terminal -e 'sh -c command1;command2;exec<TAB>bash'
gnome-terminal --tab -e 'sh -c command1;<TAB>exec<TAB>bash' \
               --tab -e 'sh -c command2;<TAB>exec<TAB>bash'

If you do need to run commands after ~/.bashrc, make it run the commands. For example, include the following code at the end of ~/.bashrc:

eval "$BASH_POST_RC"

Then to run a some code after (really, at the end of) your bashrc:

gnome-terminal -x sh -c BASH_POST_RC=\''command1; command2'\''; exec bash'

or (less heavy on the quoting)

BASH_POST_RC='command1; command2' gnome-terminal

Although I don't particularly recommend doing it this way, you may be interested in the techniques mentioned in How to start a terminal with certain text already input on the command-line?.

Gilles 'SO- stop being evil'
  • 69,786
  • 21
  • 137
  • 178
  • Yes, indeed a nice trick. Never thought of that. Now I must find a way to set the BASH_POST_RC variable differently for the specific tab. And that still seems to be a problem. A simple "gnome-terminal --tab -e 'BASH_POST_RC=ls' --tab" is not possible :-( – medihack Oct 10 '10 at 23:41
  • @Zardoz: Actually, you can trick gnome-terminal using tab characters (see my revised answer). Mind the multiple levels of quoting. – Gilles 'SO- stop being evil' Oct 11 '10 at 00:11
  • .. it works :-) ... thanks a lot for your solution and your patience. Here my complete command (works even with those spaces in the commands: gnome-terminal --working-directory="/home/zardoz/projects/my_rails_app" --tab -e 'bash -c "export BASH_POST_RC=\"rails server\"; exec bash"' --tab -e 'bash -c "export BASH_POST_RC=\"autotest\"; exec bash"' --tab – medihack Oct 11 '10 at 00:44
  • Finally made it work... After sooo many tests with quotes all the way round. Here is mine, using zsh and opening a server and a console at once: `gnome-terminal --geometry=198x44 --working-directory=/home/username/Workspace/project_name --tab --title server -e 'zsh -c "export BASH_POST_RC=\"rails server\"; exec zsh"' --tab --title console -e 'zsh -c "export BASH_POST_RC=\"rails console\"; exec zsh"'` – Augustin Riedinger Nov 26 '13 at 11:51
  • Derp, I thought it was failing because the command I ran existed very quickly, be sure to run something more than an echo to test! – ThorSummoner Aug 31 '15 at 06:41
  • @Gilles your answer lead to a little bit of confusion [here](http://unix.stackexchange.com/q/259829/22222). To clarify, when you say that *"Gnome-terminal unhelpfully splits the argument of -e at spaces rather than executing it through a shell"*, you mean that it splits the command and _then_ passes it to the shell to execute, instead of passing the whole thing to the shell and letting the shell deal with splitting, right? Not that it somehow bypasses the shell completely. The command given is still being executed via the users default shell, right? – terdon Feb 04 '16 at 12:41
  • 2
    @terdon No, `gnome-terminal -e` does not invoke a shell at all. If you run `gnome-terminal -e 'sleep 9'`, that executes the command `sleep` with the argument `9`, and no shell is involved. If you execute `gnome-terminal -e 'sleep 9;bash'` then the terminal opens and closes immediately, because `sleep` complains that `9;bash` is not a valid time interval. You can observe what's going on with `strace -f -eexecve gnome-terminal -e …` – Gilles 'SO- stop being evil' Feb 04 '16 at 12:46
  • @terdon More generally, the user's default shell is only invoked to start an interactive shell. It is never invoked to run a command — the shell might not implement a Bourne-style syntax, it might not support a `-c` argument. “Never” of course excludes buggy programs. – Gilles 'SO- stop being evil' Feb 04 '16 at 12:49
  • Great trick although the `gnome-terminal` command above did not work for me. Here is an example that works with the more recent `--` syntax for running commands in place of `-c`: `gnome-terminal -- bash -c "export BASH_POST_RC=\"command1; command2\"; exec bash"` – Dominik Mar 18 '21 at 20:35
6

When you use the -e option the gnome-terminal will run that command without starting a new shell (you can even run something like: gnome-terminal -e gedit), so if you want to run a command into the bash shell into a new terminal/tab you have to do something like this:

gnome-terminal -x bash -c "command"

But note that when "command" ends the terminal/tab will end too.

cYrus
  • 21,379
  • 8
  • 74
  • 79
  • 1
    I think you mean `gnome-terminal -x bash -c "command"` (`-e` expects a single argument). And it's fairly simple to execute a shell after `command`, at least as long as you're starting a single tab — see [my answer](http://superuser.com/questions/198015/open-gnome-terminal-programmatically-and-execute-commands-after-bashrc-was-execut/198022#198022). – Gilles 'SO- stop being evil' Oct 10 '10 at 22:40
  • `gnome-terminal -x "bash" -c "command"` worked for me. Note quotes on -x arg value. – m3nda Jul 29 '15 at 21:30
  • I get `# Option “-x” is deprecated and might be removed in a later version of gnome-terminal.` ` – MrCholo Dec 15 '18 at 00:38
  • 1
    please, what do we do since the `-x` and `-e` optons are deprecated??? – nyxee Mar 09 '19 at 11:37
  • I believe that this doesn't run `~/.bashrc` before executing the command, as originally asked by the OP. – IgNite Nov 20 '19 at 16:14