13

It seems the behavior of gnome-terminal has changed between the version shipped with Ubuntu 14 (v3.6?) and Ubuntu 18 (v3.28).

I have a script that opens a new gnome-terminal with a bunch of tabs setup to different directories for my development, and currently the first tab runs a script. The command to open the gnome-terminal with tabs looks something like this:

gnome-terminal \
   --tab --command="myscript.sh" \
   --tab --working-directory="<some dir 1>" \
   --tab --working-directory="<some dir 2>" \
   ...

This works perfectly as desired in the gnome-terminal version that shipped with Ubuntu 14 (v3.6?).

But in the gnome-terminal version that ships with Ubuntu 18 (v3.28) several things have changed:

  1. Unless I add the --window option, the tabs open in the current gnome-terminal, not a new one. Unfortunately adding the --window option opens an initial blank tab. Is it possible to open a new window with only the tabs that I specify?
  2. I now get the following notice (though it functions as before):

    # Option “--command” is deprecated and might be removed in a later version of gnome-terminal.
    # Use “-- ” to terminate the options and put the command line to execute after it.
    

    Changing my script per this guidance changes the behavior such that the command is issued to all tabs, whereas before I could apply a unique command to each tab. Does this mean the ability to run a separate command per tab has been deprecated, or am I missing something?

I appreciate suggestions on how to change my script to support the old behavior in the newer gnome-terminal.

4 Answers 4

4

this opens multiple tabs. i think it is cleaner to keep each tab on a separate line. if you want a new window for each, omit --tab

note the big difference with -- over -e/--command is that the arguments are not in quotes

gnome-terminal --title "Frontend Web App" --tab --working-directory ~/projects/front-end-app -- npm run serve
gnome-terminal --title "API Server" --tab --working-directory ~/projects/api-server -- ./run-local.sh
3

It is a bit unfortunate that gnome-terminal has deprecated -e. This makes launching an instance running multiple tabs with different commands tricky. Here is my approach:

I create an executable launch_project_foo script somewhere in my path. A typical project launch file may look like:

#!/bin/bash

BASE_DIR=~/git/ProjectFooBaseDir

cat << EOF > /tmp/bootstrap_tabs.sh
gnome-terminal --tab -t "Docker" --working-directory="$BASE_DIR/backend" -- \
  zsh -is eval "docker-compose up"
gnome-terminal --tab -t "Backend" --working-directory="$BASE_DIR/backend" -- \
  zsh -is eval "npm start"
gnome-terminal --tab -t "Frontend" --working-directory="$BASE_DIR/frontend" -- \
  zsh -is eval "npm start"
gnome-terminal --tab -t "Git" --working-directory="$BASE_DIR"
EOF

gnome-terminal --window --maximize -- bash /tmp/bootstrap_tabs.sh

Important: This relies on having an eval hook in .zshrc, as explained below.

A few notes:

  • The main gnome-terminal call actually creates a "zeroth" tab for the bootstrapping, but since it closes immediately this isn't really observable. If you place a sleep in the bootstrap script you'll see what I mean.

  • To allow for variable substitution the heredoc must not use a quoted 'EOF', see using variables inside a bash heredoc.

  • The last tab creates a regular terminal for normal work.

  • The other tabs don't launch the processes directly, because doing so would mean that if the process terminates the tab is gone. The solution to that problem is somewhat shell specific. I'm using zsh here, and rely on having an eval hook in the .zshrc. It is possible to avoid the eval hook and simply use e.g. zsh -ic "<commands>; zsh -i". However this has the drawback that the when killing the commands with CTRL + C (which is common for infinitely running commands like npm start) the entire tab will close, because the outer shell instance terminates. The approach with the eval hook avoids that and allows to keep tabs open even in case of SIGTERMs.

  • Commands can be chained as normal, and in practice I often use sleep 10; npm start; to wait for something from another tab (like docker-compose) to be ready.

1
  • 2
    This actually works! (It is easy to modify this for bash)
    – zkytony
    Commented Apr 24, 2023 at 20:49
3

I had the same issue, and after a huge number of attempts I found the following solution

gnome-terminal -- bash -c "myCommand -some-args; bash"
gnome-terminal -- bash -c "myOtherCommand -some-args; bash"
4
  • 2
    That opens individual windows for me. And what if other gnome-terminal instances are around -- how would this approach make sure to group exactly these commands into one window with multiple tabs?
    – bluenote10
    Commented Mar 4, 2021 at 9:27
  • 1
    @bluenote10 put --tab after gnome-terminal but before -- Commented Jun 8, 2021 at 19:22
  • as to which window, --tab will do this Open a new tab in the last-opened window with the default profile (from gnome-terminal --help-all) Commented Jun 8, 2021 at 19:24
  • also, note the & is not needed on the end Commented Jun 8, 2021 at 19:26
1

Best way, IMHO, is to forget about gnome-terminal. Install mate-terminal instead, which is a clone of the old gnome-terminal, and it retains the good stuff like ability to name the tabs...
Here's my startup script, which creates three named tabs, and each could be in a different directory...

#!/bin/bash
mate-terminal \
--hide-menubar \
--geometry=130x12+1+800 \
--tab -t "vpn" \
    --tab -t "home" \
    --tab --working-directory="/ddr/buppo/bw/bw-b/sn" -t "sn"
2
  • Thank you a lot! Work like a charm! Commented Nov 15, 2023 at 4:50
  • this is almost as bad as running xterm tho (feels foreign to the environment)
    – nhed
    Commented Nov 30, 2023 at 21:45

You must log in to answer this question.

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