Kde, opening a new terminal window to ssh from bash script

I have a bash scrip that does some environment setup, one of the steps require me to use SSH tunneling for licensing. The script I have works fine on a gnome environment, but I’m having trouble getting it to work on kde.

gnome-terminal -- ssh -L <>

What’s the equivalent of that for kde? I’ve tried konsole --new-tab, this opens a new tab but doesn’t execute anything and I can’t go back to my previous terminal unless I close this new window.

I’ve also tried using xterm with xterm -e ssh -L but same issue, I can’t use my previous terminal without closing this session and doing so would result in the license check failing.

Answer

Analysis

Your command:

gnome-terminal -- ssh -L …

when run from a shell or from a shell script runs synchronously. The shell waits for it to exit before accepting the next command. The important thing is gnome-terminal does few things to exit early.

If gnome-terminal runs from within gnome-terminal (so the environment contains GNOME_TERMINAL_* variables) then the new gnome-terminal process will delegate the task to the already running gnome-terminal and exit.

If not from within gnome-terminal then yet another new gnome-terminal will be created to handle the task with no connection to the original terminal and your script. The gnome-terminal process your script spawned will exit after delegating the task.

So in any case ssh will run under gnome-terminal that is not a child of your script. The child of your script will exit early and allow the script to continue.

With konsole or xterm it’s different. The very process your script spawns handles the task of being the terminal emulator for ssh, so your script doesn’t continue until you close the new window.


Solutions

There are few solutions:

  • Use gnome-terminal. You don’t need full Gnome desktop to use this program. I use KDE Plasma and I have installed gnome-terminal for testing, to be able to answer questions like this.

    Your script will (still) depend on gnome-terminal.

  • Spawn xterm (or konsole or whatever) asynchronously: xterm -e ssh -L … &. I think this may be the simplest solution. The xterm process will be a child of your script but the script won’t wait for it. Note the script cannot easily tell if ssh authenticated yet and if port forwarding works; but I guess the same problem occurs with gnome-terminal, so probably your script takes this into consideration.

    Your script will depend on xterm (or konsole or whatever).

  • Use a terminal multiplexer: screen or tmux.

    Your script will depend on screen or tmux. This seems no better than the above alternatives, but these terminal multiplexers are not associated to any desktop environment and they work even without any desktop. I’m mentioning them to make the answer more complete.

  • Run ssh without creating any additional terminal. See below.

    Your script will get rid of one dependency.


Running ssh without creating additional terminal

In many cases this solution is the most elegant. It may or may not be good for you. You haven’t revealed what your ssh does on the remote side. If it’s only about forwarding ports (so you can use ssh -N) or if the command to run on the remote side is non-interactive then you should use ssh -f:

-f
Requests ssh to go to background just before command execution. This is useful if ssh is going to ask for passwords or passphrases, but the user wants it in the background. […]

Even if your ssh is not going to ask for passwords/passphrases, -f is better than ssh … & because you can use it with -o ExitOnForwardFailure and check its exit status before you assume the tunnel works.

Additionally use -o ControlMaster=yes -o ControlPath=… (in short -MS …) so you can easily terminate the master ssh later with -O exit. In this answer of mine you will find a script that does this. A perfect script would terminate the master connection and clean up before exiting, even if terminated with Ctrl+C (use trap).

OTOH if you can set things up so ssh does not ask for anything then consider autossh in the background (autossh … &) to create a tunnel and keep trying to renew it in case the connection breaks. See the last part of this other answer.

Leave a Reply

Your email address will not be published. Required fields are marked *