26

I am new to linux shell scripting. I want to write a shell script which will open terminal with multiple tabs; it should run rtsp client app in each tab.

For this, I have gone through question here in this forum and tried to code like bellow,

tab="--tab-with-profile=Default -e "
cmd="java RunRTSPClient"
for i in 1 2 3 4 5
   do
#   
   foo="$foo $tab $cmd"         
   done
gnome-terminal $foo
exit 0

This is running and opens the terminal window with tabs but suddenly it will close. I am not getting any errors.

Radu Rădeanu
  • 169,590
user172001
  • 261
  • 1
  • 3
  • 3

2 Answers2

24

I came up with my own answer. I think this is a better approach because:

  1. I can understand it. I'm not a bash expert and no explanation was given in the more popular answer for what is ..., ${}, -e, or @
  2. It allows you to easily customize the title and command for each tab
  3. Did I say it's a lot easier to understand?

Note that the ; $SHELL at the end of each gnome-terminal command is what keeps the terminal window open. Otherwise it would immediately close.

Old version [I recommend the new version below, instead]:

  • works on older versions of gnome-terminal, such as from Ubuntu 14.04.
  • gnome-terminal disabled the --title option sometime on or after version 3.16.2 (see comment by Ivan Kozik under this answer, and see my comments below my answer), however, so although the rest of the script below does still work in modern versions of gnome-terminal and Ubuntu, setting the title of each tab with --title does NOT. See the New version below for an alternative that works everywhere.

Old code (setting the tab title like this doesn't work anymore in Ubuntu 16 or 18 or later, and the --command option is unfortunately also now deprecated):

title1="tab 1"
title2="tab 2"
title3="tab 3"

cmd1="cd /etc" cmd2="cd ~/Documents" cmd3="cd /usr/local"

gnome-terminal --tab --title="$title1" --command="bash -c '$cmd1; $SHELL'"
--tab --title="$title2" --command="bash -c '$cmd2; $SHELL'"
--tab --title="$title3" --command="bash -c '$cmd3; $SHELL'"

New version [USE THIS ONE!] (Added 7-11 Feb. 2020):


New code--works perfectly in all versions of the gnome-terminal and terminator terminals (and could be extended to work with more terminals if desired), and has been tested in Ubuntu 14.04, 16.04, 18.04, and 20.04. You can find the latest and best version of this in my personal "~/.bash_aliases" and "~/.bash_aliases_private files in my dotfiles project here. Read the readme, and search the "~/.bash_aliases" file for the section called "CUSTOM TERMINAL TABS & TITLES". In the "~/.bash_aliases_private" file, search for the section called "CONFIGURATION FOR gs_open_default_tabs Bash function". See also the "open_programming_tools.sh" script and "open_programming_tools.desktop" desktop launcher file, both of which are used to quickly open up your terminal with all tabs as you've configured.

All of the below information past this point should work but is not up-to-date with my latest changes found in my repo just above. Take a look there for my latest techniques and scripts.


  1. Setting the tab title like this below DOES work in ALL versions of gnome-terminal now, so it works fine in Ubuntu 16 and 18 and 20 and later!

  2. See here and the references at the very bottom of this answer for a lot more details and further understanding: https://unix.stackexchange.com/questions/177572/how-to-rename-terminal-tab-title-in-gnome-terminal/566383#566383

  3. Note that the gnome-terminal --command (-e) and --title options are unfortunately now deprecated, hence this difficult work-around. Here's the warning I get if I call gnome-terminal with one of the deprecated options from the command-line:

     # 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.
    
  4. I'll be using an interesting custom set-title function with some special use of exported variables and the ~/.bashrc file since it gets automatically sourced each time an interactive (-i) bash shell is opened.

1st, add this to the bottom of your ~/.bashrc file:

Update the DEFAULT_TABS_TITLE and DEFAULT_TABS_CMD variables as you see fit.

# Function to allow a user to arbitrarily set the terminal title to anything
# Example: `set-title this is title 1`
set-title() {
    # Set the PS1 title escape sequence; see "Customizing the terminal window title" here: 
    # https://wiki.archlinux.org/index.php/Bash/Prompt_customization#Customizing_the_terminal_window_title
    TITLE="\[\e]2;$@\a\]" 
    PS1=${PS1_BAK}${TITLE}
}

Back up original PS1 Prompt 1 string when ~/.bashrc is first sourced upon bash opening

if [[ -z "$PS1_BAK" ]]; then # If length of this str is zero (see man test) PS1_BAK=$PS1 fi

Set the title to a user-specified value if and only if TITLE_DEFAULT has been previously set and

exported by the user. This can be accomplished as follows:

export TITLE_DEFAULT="my title"

. ~/.bashrc

Note that sourcing the ~/.bashrc file is done automatically by bash each time you open a new bash

terminal, so long as it is an interactive (use bash -i if calling bash directly) type terminal

if [[ -n "$TITLE_DEFAULT" ]]; then # If length of this is NONzero (see man test) set-title "$TITLE_DEFAULT" fi

DEFAULT_TABS_TITLE1="tab 1" DEFAULT_TABS_TITLE2="tab 2" DEFAULT_TABS_TITLE3="tab 3"

DEFAULT_TABS_CMD1="cd /etc" DEFAULT_TABS_CMD2="cd ~/Documents" DEFAULT_TABS_CMD3="cd '$HOME/temp/test folder'" # Use quotes like this if there are spaces in the path

open_default_tabs() { gnome-terminal --tab -- bash -ic "export TITLE_DEFAULT='$DEFAULT_TABS_TITLE1'; $DEFAULT_TABS_CMD1; exec bash;" gnome-terminal --tab -- bash -ic "export TITLE_DEFAULT='$DEFAULT_TABS_TITLE2'; $DEFAULT_TABS_CMD2; exec bash;" gnome-terminal --tab -- bash -ic "export TITLE_DEFAULT='$DEFAULT_TABS_TITLE3'; $DEFAULT_TABS_CMD3; exec bash;" }

If length of this is NONzero

if [[ -n "$OPEN_DEFAULT_TABS" ]]; then OPEN_DEFAULT_TABS= # reset to an empty string so this only happens ONCE open_default_tabs exit 0 # close the calling process so only the "default tabs" are left open fi

2nd, call the open_default_tabs function from any terminal.

Since you just updated your ~/.bashrc file, you need to let your terminal know about it before it will give you access to your new functions and features. You need to "re-source" your ~/.bashrc file. So, close and reopen your terminal, OR call . ~/.bashrc or source ~/.bashrc to re-source your ~/.bashrc file. Then, simply call open_default_tabs and you'll magically get all your tabs you want opened and titled and cded into the directories you set, like this!

enter image description here

3rd (Optional), create a script and desktop file so you can just double-click the desktop file to load these tabs.

open_tabs.sh:

# Export this variable so your ~/.bashrc file will see it and do the magic.
export OPEN_DEFAULT_TABS=true
# Open a new terminal window, which by default also sources your ~/.bashrc file again, 
# thereby kicking off the process since you set the `OPEN_DEFAULT_TABS` variable just above.
gnome-terminal 
OPEN_DEFAULT_TABS=      # set this variable back to an empty string so it's no longer in force
unset OPEN_DEFAULT_TABS # unexport it

open_tabs.desktop:

[Desktop Entry]
Name=Open Tabs
Name[en_US]=Open Tabs
Comment=
Exec=/path/to/open_tabs.sh
Icon=terminal
Terminal=false
Type=Application
StartupNotify=true

Then do:

chmod +x open_tabs.sh
chmod +x open_tabs.desktop

Place open_tabs.desktop on your desktop and double-click it.

Voila! It's magical! You'll get a new terminal window with 3 titled tabs, each in the proper directory you set based on the commands you configured in your ~/.bashrc file.

Download this and more:

Note that this code, as well as many more useful configuration settings and scripts, have been placed into my dotfile project: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles. This code is here:

  1. "eRCaGuy_dotfiles/home/README.md" readme
  2. "~/.bash_aliases" file
  3. "~/.bash_aliases_private" file
  4. "open_programming_tools.sh" script
  5. "open_programming_tools.desktop" desktop launcher file

References:

1. My pleas for help in the process of creating the "New code" version:

  1. bash: "command not found" when calling function defined in ~/.bashrc file in `bash -c` command while opening gnome-terminal tab
  2. Open terminal with multiple tabs and execute application which uniquely modifies PS1 variable for each tab

2. Others:

  1. https://wiki.archlinux.org/index.php/Bash/Prompt_customization#Customizing_the_terminal_window_title
  2. https://unix.stackexchange.com/questions/177572/how-to-rename-terminal-tab-title-in-gnome-terminal/566383#566383
  3. How to run a script without closing the terminal?
  4. https://stackoverflow.com/questions/16618071/can-i-export-a-variable-to-the-environment-from-a-bash-script-without-sourcing-i
  5. https://www.shellscript.sh/variables1.html

Responding to comments below

To @egmont:
To answer your question: here's what I get when I do this: gnome-terminal --tab --title abc -e 'sleep 10' --tab --title def -e 'sleep 10'.

$ gnome-terminal --tab --title abc -e 'sleep 10' --tab --title def -e 'sleep 10'
# Option “-e” 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.
# Option “-e” 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.

HOWEVER, IT DOES OPEN UP 2 NEW TABS INSTANTLY, with titles set to abc and def. After ~10 seconds, however, the tabs auto-close and do NOT remain open.

  • 1
    "gnome-terminal disabled the --title option sometime on or after version 3.16.2" – This is not true, --title works fine, it's neither removed nor deprecated. What might happen though is that your shell immediately replaces that title with its own one (e.g. via PS1). – egmont Feb 12 '20 at 22:46
  • Perhaps, but I'm not convinced you are right. I am running gnome 3.28.2 (see "About" GUI screen from Applications menu), and when I do gnome-terminal --tab --title "hey" from the terminal, I get a new tab that opens but it does NOT have the title set to "hey". Additionally, man gnome-terminal shows no --tab option, and echo $PS1 | grep "2;" shows no results, indicating that the PS1 escape sequence required to set a title (\[\e]2;) is NOT present, so PS1 is not overriding any title. In other words, --title seems to be not present and not functional. – Gabriel Staples Feb 12 '20 at 23:07
  • Also see the comment by Ivan Kozik under this answer here: https://askubuntu.com/a/22417/327339. – Gabriel Staples Feb 12 '20 at 23:11
  • What does this command do? gnome-terminal --tab --title abc -e 'sleep 10' --tab --title def -e 'sleep 10' – egmont Feb 13 '20 at 08:17
  • Mainstream gnome-terminal doesn't ship a manual page, it's added by Debian or Ubuntu and is not maintained. The escape sequence that contains 0; instead of 2; also sets the title, and it could even reside in PROMPT_COMMAND instead of PS1. – egmont Feb 13 '20 at 08:17
  • 1
    Oh, you're right. The --title option was indeed removed at one point, but then later resurrected. I didn't remember this. – egmont Feb 13 '20 at 08:21
  • @egmont, see my response to you added to the bottom of my question. When I do gnome-terminal --tab --title abc -e 'sleep 10' --tab --title def -e 'sleep 10' it gives me a bunch of warnings about -e (--command equivalent) being deprecated, then it opens 2 new tabs, properly titled, then it auto-closes them after ~10 seconds. – Gabriel Staples Feb 13 '20 at 22:41
  • So the --title command works for you, it's clearly demonstrated. Of course it closes when the specified command, sleep 10 in this example, completes. As the next step, you may want to replace this command by a shell that does not tamper with the title, gnome-terminal's --title option will still take effect. – egmont Feb 14 '20 at 08:19
  • 1
    To amend a previous comment: Out of the currently supported Ubuntu releases, only the oldest (Xenial 16.04) ships a gnome-terminal where --title is not supported. – egmont Feb 14 '20 at 09:19
  • There is an issue with this solution - the title only appears after the initial command/process is finished. If I open 5 tabs with different java programs, then the titles remain "Terminal" for each of them, until the java process if finished, which defeats the whole point of having a title – Olav Kokovkin Jun 10 '22 at 09:17
  • @OlavKokovkin, did you use the old version or the new version of my solution? There was a period of time where the old version quit working, but it's possible it works again now, as I vaguely remember some discussions about how the bash developers undeprecated the things which were deprecated and which made the old version quit working. – Gabriel Staples Jun 10 '22 at 14:06
15

Use this variant of the script to do what you want:

#!/bin/bash

tab="--tab-with-profile=Default"
cmd="bash -c 'java RunRTSPClient';bash"
foo=""

for i in 1 2 3 4 5; do
      foo+=($tab -e "$cmd")         
done

gnome-terminal "${foo[@]}"

exit 0

Generally, a script like this:

#!/bin/bash

tab="--tab"
cmd="bash -c '<command-line_or_script>';bash"
foo=""

for i in 1 2 ... n; do
      foo+=($tab -e "$cmd")         
done

gnome-terminal "${foo[@]}"

exit 0

will open a new terminal with n tabs executing the <command-line_or_script> in each tab. This can be very useful when you want for example to open a terminal with some tabs with the interpreter at a specific path (using cd /path in the above script).

Also, read man bash, this post and this post to understand the changes.

I have tested these scripts and they work.

Radu Rădeanu
  • 169,590
  • Same as i told It just displays and closes and no error also getting. How to fix this issue?. – user172001 Jul 02 '13 at 13:18
  • ok now its showing the windows with tabs but not running the app in any tab. and also explain me a bit, how this has fixed the window display issue. – user172001 Jul 02 '13 at 13:22
  • @user172001 Now it's working, check the new edits! – Radu Rădeanu Jul 02 '13 at 18:34
  • this is pretty cool. +1 – Nishant Nov 08 '13 at 10:59
  • 1
    I tried adding cmd1 && cmd2 into the command string to run multiple commands. It only seems to run the first one. Am I doing something blatantly wrong? – byxor Nov 05 '16 at 12:12
  • If you could break this down with a thorough explanation of each line and symbol, and show what gnome-terminal "${foo[@]}" expands to (and how/why), that'd be super helpful. – Gabriel Staples Apr 20 '18 at 02:56
  • `# Option “-e” 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.` What do we do now?

    – Gabriel Staples Feb 11 '20 at 06:10
  • I get an error which says: Failed to execute child process "bash -c '<command>';bash" (No such file or directory) – M F Feb 01 '23 at 16:17