0

I'm connecting using OpenSSH to a Linux server where I have a tmux session where I do certain compiling work which takes a long time. Now I would like to be get right away a notification on my Linux client (the computer I'm connecting from) once a certain command which takes a long time finally is complete.

Locally, I know of several ways of how to get notified using a pop-up, playing something, … (1), (2) by running a certain command. Now I would need to do the same remotely. A perfect solution would be some sort of feedback channel right in ssh but I'm not aware of any such functionality.

And please no email-based solution as suggested in (3). I'm getting already too many work emails and I'm trying to dial down the amount of emails for something just to acknowledge but not for reading, storing, forwarding or replying to (for this I even created a separate email account for which I don't get real-time notifications).


  1. https://superuser.com/questions/345447/how-can-i-trigger-a-notification-when-a-job-process-ends
  2. https://askubuntu.com/questions/277215/make-a-sound-once-process-is-complete
  3. Alert when running process finishes
  • 1
    You say you are using tmux on the server. One big reason for using tmux is that it allows you to disconnect and reconnect. Do you need to be notified if you are disconnected, or can we assume that there is still an ssh connection running? – icarus Nov 20 '16 at 17:02
  • @icarus If it was possible even if disconnected it would be better but either case is OK. – phk Nov 20 '16 at 17:04
  • ssh already implements a reverse channel for X11 connections. So start your ssh with -X and at the appropriate time run any X11 notifier on the remote, eg xmessage. – meuh Nov 20 '16 at 18:30
  • @meuh Interesting idea thanks. I guess it would require installing a lot of packets on the server though. :/ – phk Nov 21 '16 at 11:08
1

The simplest solution is to use the exit from tmux, by issuing a tmux detach, to close the ssh connection, then send a notification, and then reconnect and attach back to the tmux. Eg with the script

ssh -t remote tmux
notify-send done
ssh -t remote tmux attach

You run tmux, and start off your long-running command, then type-ahead the command

tmux detach

which will run when the long command is done. This will close tmux, close the ssh, and the notify-send will show your desktop message. A new ssh will reattach exactly where you left off.

6

For the case that there is still an ssh connection, you can use port forwarding. I am going to call the two machines laptop and server, with the latter where the long running job is being executed. The principle advantage I see with this is for ad-hoc setups, for example connecting from laptop in a coffee shop. For that use case you will be running behind a NAT, probably can't open up ports using PNP. It usually doesn't require anything to be installed on the server. If this doesn't apply then go with the suggestion of setting up an ssh service on the laptop.

Invoke ssh on laptop and ask it to forward the remote tcp port 4000 to the local port 5000. In practice you would use the same port number at both ends, I am using different ones to make it clearer what is going on. Here I am using the openssh command line

ssh -R 4000:127.0.0.1:5000 username@server

Connect to tmux, start you job, arrange when the long running job finishes it writes to port 4000.

(long_running job with params ; echo "$?" > /dev/tcp/127.0.0.1/4000) &

If you don't have /dev/tcp and it is not emulated by the shell, then you could use something like echo "$?" | netcat 127.0.0.1 4000

Meanwhile on laptop listen for the connection on port 5000, presumably in a different window.

netcat -l -p 5000; do_something_to_alert_the_local_user.

The netcat will block waiting for the server to connect to port 4000, which will be forwarded via the encrypted ssh tunnel to port 5000. After the connection closes at the end of the echo the local netcat will exit and the do_something_to_alert_the_local_user will run.

0

If you have a OpenSSH server running on the client you can configure it to force a certain command to be run for a particular key. If done correctly this key can only be used to trigger this notification and not for any significantly nefarious stuff.

To make things less confusing (because in this case we have both sides action either client or server) I will call the local machine, i.e. the client you connect to the remote server to start the long-lasting task on, Alice. Bob will then the server where to start the compile task on which is then supposed to notify Alice about the completion of the task.

For this you would have you basically just generate a key using ssh-keygen -f notif_key and then add the public key (notif_key.pub) to a separate line in your Alice's .ssh/authorized_keys but prepended with:

command="/path/to/notifier.sh \"$SSH_ORIGINAL_COMMAND\"",no-port-forwarding,no-x11-forwarding,no-agent-forwarding ssh-rsa …

(ssh-rsa … stands for the public key.)

notifier.sh is a script on Alice's side then which then calls the notification command (of course you can start right away if possible, just note that the whole line is executed in a shell).

On Bob's side you can then trigger the notification on Alice's side using ssh, so all in all you run on Bob inside the tmux session:

time-consuming-command; ssh -i notif_key user@alice_pc foobar

And that's it!

BTW, $SSH_ORIGINAL_COMMAND is a placeholder for all the extra command line for the ssh command which then gets forwarded to the forced command. This way you could customize the particular notification from Bob, e.g. for when you run multiple tasks this way at once at once.

Example notifier.sh with that in mind:

#!/bin/sh
some-notification-command --message "Task '$*' is done!"
echo 'Note to Bob: Alice has been notified.'

All in all, this solution is far from optimal. It requires an OpenSSH server on the client and is quite some hassle to configure. I hope better solutions exist.

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.