1

I am writing a bash script where I pretend to open a new terminal window (in this case a gnome-terminal), execute some commands and change the title of the terminal window.

In order to change the title of the terminal window I am using the function set-title as proposed in this answer. The approach works perfectly when I open manually a new terminal and type inside the terminal set-title MY_TITLE. But in this case, from within a bash script it is not working even if I source the .bashrc file.

#!/bin/bash

gnome-terminal -- /bin/bash -c "echo Hello from terminal 1; set-title Terminal 1; exec /bin/bash";

gnome-terminal -- /bin/bash -c "source ~/.bashrc; echo Hello from terminal 2; set-title Terminal 2; exec /bin/bash";

The two new opened terminals show the same error:

/bin/bash: set-title: command not found

It is obvious that the bash interpreter does not find the function set-title, but I do not know how to force the loading of the .bashrc file when the gnome-terminal is opened.

3
  • 1
    I hadvebeen down the rabbit hole. I ended up using xfce4-terminal. With just, for example: xfce4-terminal --title foo you're good to go. Feb 1, 2021 at 14:46
  • 2
    ~/.bashrc usually starts with a line which skips the rest of the file if the shell is not interactive (as with bash -c '...').
    – user313992
    Feb 1, 2021 at 15:29
  • With that being said, you don't need any (broken, as in the answer you point to) function in your ~/.bashrc, you can just printf '\033]2;%s\033\\' 'Terminal 1' anywhere you want.
    – user313992
    Feb 1, 2021 at 15:36

1 Answer 1

2

I will answer my own question but before explaining the two solutions I have found, I will explain why what I was trying to do did not worked.

Why my initial approach was wrong

If you have custom functions in your ~/.bashrc file, like in my case the one for setting the title of the terminal window, those functions will not be available in a terminal window that is opened from a bash script that executes commands in an automated way (as in the example of my question).

Thanks user414777 for the hint. You were absolute right. My ~/.bashrc file contains the following code at the beginning:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

By printing the option flags $- the result is hB (as expected is not an interactive shell), so obviously the set-title function that I have at the end of the ~/.bashrc, will never be added to the shell.

Solution 1 (Recommended): Using xfce4-terminal

As schrodigerscatcuriosity suggested, this is the easiest solution for the problem. You might not like to install another terminal tool; if (like in my case) you are using Gnome and you use by default gnome-terminal, but the good side is that you can use the xfce4-terminal for the bash scripts and the gnome-terminal for your "human" interaction, so besides the titles you also have an extra level of categorization (in case you have many terminal windows opened).

The xfce4-terminal works a bit different than the gnome-terminal from within a bash script, but nothing you can not really figure out. In any case you can find below the solution with xfce4-terminal:

#!/bin/bash

xfce4-terminal --title "Terminal 1" -e "bash -c 'echo Hello from terminal 1; exec /bin/bash'" &

xfce4-terminal --title "Terminal 2" -e "bash -c 'echo Hello from terminal 2; exec /bin/bash'" &

Solution 2: Using xdotool

Another solution that I found to the problem is using xdotool. xdotool is a command line tool that can simulate/automate human interaction in the X11 window system.

This solution is overengineering the initial problem since it creates other issues such as the synchronization between the bash script and the X windows system, therefore it is necessary to introduce sleep commands in the bash script to give time to the X window manager to process the events. This synchronization issues make this solution not reliable since it does not works in 100% of the cases and the sleeping times need to be adapted to the speed of the window system.

Despite I do not recommend to go for this solution for the exposed problem in the question, I decided to introduce the solution in the answer for the shake completeness. Someone else might find it useful to apply this approach for some other purpose:

#!/bin/bash

function set-title(){
    sleep 0.2
    
    # local WINDOW_ID=`xdotool getactivewindow`
    # local P_ID=`xdotool getactivewindow getwindowpid`
    # echo "the window id is: $WINDOW_ID with PID: $P_ID"

    xdotool type "set-title $@"
    xdotool key KP_Enter
    sleep 0.2
}


gnome-terminal -- /bin/bash -c "echo Hello from terminal 1;echo $-; exec /bin/bash";
# xdotool search --onlyvisible --class 'gnome-terminal'
set-title "Terminal 1"


gnome-terminal -- /bin/bash -c "echo Hello from terminal 2; exec /bin/bash";
# xdotool search --onlyvisible --class 'gnome-terminal'
set-title "Terminal 2"

In this case, the function set-title included in the ~/.bashrc file will work because after the commands have been executed in the gnome-terminal, the last instruction is /bin/bash. It loads the shell again and the next commands are forwarded to the terminal using xdotool, which creates the same events that a human would generate with the input devices (mouse, keyboard, etc ...).

You must log in to answer this question.

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