2

What I'm trying to do:

  1. Write a script to open 3 tabs.
  2. cd into a different folder in each tab (ie: run a unique command).
  3. get each tab to have a unique title by modifying its local PS1 variable
  4. Ensure each tab stays open after the script is run

I want this scripted so I can click the script on my Desktop and have it open up terminals as I'd like for my daily development environment.

Description:

I have this script to try and open 3 terminal tabs with unique commands to be run in the tabs:

open_tabs.sh

#!/bin/bash

gnome-terminal --tab -- bash -ic "set-title title 1; exec bash"
gnome-terminal --tab -- bash -ic "cd ~; set-title title 2; exec bash"
gnome-terminal --tab

When I run it with ./open_tabs.sh, it opens up 3 new tabs, but unfortunately set-title doesn't work to set the tab title! It appears the PS1 variable isn't staying set with my set-title call. The exec bash is there to keep the tab open, per this answer and comments underneath it.

I have set-title defined as a function in ~/.bashrc like this. Its purpose is to set the title string at the top of any terminal window. It works perfectly when I use it manually. Ex: set-title hey how are you? will put "hey how are you?" at the top of my terminal window.

# From: https://unix.stackexchange.com/questions/177572/how-to-rename-terminal-tab-title-in-gnome-terminal/566383#566383
set-title() {
    # If the length of string stored in variable `PS1_BAK` is zero...
    # - See `man test` to know that `-z` means "the length of STRING is zero"
    if [[ -z "$PS1_BAK" ]]; then
        # Back up your current Bash Prompt String 1 (`PS1`) into a global backup variable `PS1_BAK`
        PS1_BAK=$PS1 
    fi

    # Set the title escape sequence string with this format: `\[\e]2;new title\a\]`
    # - See: https://wiki.archlinux.org/index.php/Bash/Prompt_customization#Customizing_the_terminal_window_title
    TITLE="\[\e]2;$@\a\]"
    # Now append the escaped title string to the end of your original `PS1` string (`PS1_BAK`), and set your
    # new `PS1` string to this new value
    PS1=${PS1_BAK}${TITLE}
}

How do I fix this so that each tab runs a command, sets its title by modifying its PS1 variable, and stays open?

Note that gnome-terminal has deprecated its --title and --command options, hence these work-arounds.

Related:

  1. bash: "command not found" when calling function defined in ~/.bashrc file in `bash -c` command while opening gnome-terminal tab
  2. https://unix.stackexchange.com/questions/177572/how-to-rename-terminal-tab-title-in-gnome-terminal/566383#566383
  3. Open Terminal with multiple tabs and execute application <== this is what I'm really trying to solve, but gnome-terminal's --command (-e) option is now deprecated!

    # 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. How to run a script without closing the terminal?

0

As is the case with most programming, solving the problem was extremely hard. I had to study a bunch about Bash variables, and how to use export and source (or the POSIX dot operator, .), and how bash loads, and what interactive -i bash mode was, etc etc.

I found man bash and man test to also be useful. Here's how to do what I want to do, which is:

  1. Write a script to open 3 tabs.
  2. cd into a different folder in each tab (ie: run a unique command).
  3. get each tab to have a unique title by modifying its local PS1 variable
  4. Ensure each tab stays open after the script is run

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

# 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

2nd, create this script to open 3 unique tabs with 3 unique cd commands and 3 unique titles:

open_tabs.sh:

gnome-terminal --tab -- bash -ic "export TITLE_DEFAULT='title 1'; cd ..; exec bash;"
gnome-terminal --tab -- bash -ic "export TITLE_DEFAULT='title 2'; cd ../..; exec bash;"
gnome-terminal --tab -- bash -ic "export TITLE_DEFAULT='title 3'; cd ../../..; exec bash;"

Now open up a terminal and run the open_tabs.sh script:

./open_tabs.sh

Voila! It's magical! These 3 new tabs are now shown at the top of my terminal, and each has done the proper cd command I set, and each has the proper title I set!

enter image description here

This will all be placed into my dotfiles project: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles.

Full and final solution: see here: Open Terminal with multiple tabs and execute application

-1

I think you should use & to get your processes to run in background.

https://www.tecmint.com/run-linux-command-process-in-background-detach-process/

2
  • Can you please demonstrate it and see how it would work? The command is in most cases just cd ing Into a directory and setting the Prompt String 1 PS1 variable. It seems to me making it run in the background wouldn't help. Nevertheless I'll give it a shot when I get to a computer again. – Gabriel Staples Feb 11 '20 at 20:07
  • I am unable to find any way to make & make a difference. If you can be more explicit to demonstrate how it will help I'd appreciate it. – Gabriel Staples Feb 11 '20 at 21:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.