I want to write a bash script which can ssh into a server, start a continuous background process (infinite python script) and exit the server. Here is what I have tried:

ssh user@domain "python3 script.py &"

ssh user@domain "python3 script.py & exit"

ssh user@domain "nohup python3 script.py & exit"

None of them are working. The script starts successfully but I am unable to exit the server and it stays logged in.

  • What do you mean by 'exit the server'? Do you mean terminate the SSH session? – Michael Harvey Mar 13 '20 at 20:03
  • You want to run contentiously forever, and then exit. HOW? How can you do anything after forever? -- I edited the title to say what I hope you meant to say. – ctrl-alt-delor Mar 13 '20 at 20:05
  • The new title precisely describes my problem and yes I meant to say exit the ssh session. – user13058437 Mar 13 '20 at 20:30

Try a terminal multiplexer, tmux is great. I usually don't like giving advice where you may have to install something but tmux is a really handy app to have in your tool belt. (may already be installed)

You can fire off your app wrapped in tmux detach close you laptop go somewhere else log back in and re attach to your session still running in tmux. If your OS is older screen does similar but I prefer tmux.

you can launch a new app from command line or app formatted like this

tmux new-session "command1"

tmux new-session "ping"

But you probably should name your sessions. Now short hand new session named muxping that starts in the background. The -d is detached.

tmux new -d -s muxping "ping"

now show it in background

tmux ls

attach to it

tmux a

In addition you can split screen and do many very handy things in tmux. There are many sites with tmux cheat sheets that simplify the large man page. it is pretty easy to get started.

  • What does tmux have to do with running commands on remote systems? – Greg A. Woods Mar 13 '20 at 21:38
  • tmux would have to be on the remote system. I use it on our jump server. If I needed to start a long running test I can start it on the remote server with ssh user@domain "tmux new -d -s muxping 'ping'" Now log off everything go home and re attach to the long running process to finish monitoring etc. – Mark Stewart Mar 13 '20 at 21:51

The nohup command isn't doing what you think -- it ignores a hangup signal so that the (terminal) connections on STDIO can be dropped without the terminal driver sending SIGHUP to attached processes, but nohup doesn't close its own STDIO connections, and it in effect passes them on to the process it starts, and thus sshd will wait until the process terminates and those descriptors are closed as a result.

So you need to make sure the process you start also isn't connected to the STDOUT and STDERR descriptors given to it by sshd (STDIN is already open on /dev/null), and you can do that by redirecting them (either to a file, or to /dev/null). The nohup command isn't strictly needed as nothing will send SIGHUP when the SSH connection drops.

Try this:

ssh user@domain "python3 script >/dev/null 2>&1 &"
  • Ssh does not create a pseudo-tty when a command argument is given, unless the -t option is used. Since there's no tty, nohup is not needed. Simply ssh user@domain 'python3 ... </dev/null >/dev/null 2>&1 &' should do. – mosvy Mar 13 '20 at 21:21
  • @user13058437 I'm not able to test it right now, but I think that just ssh user@domain 'python3 ... >/dev/null &' (without any other redirection) will do. Unless the python is killed by systemd (unlikely though possible). – mosvy Mar 13 '20 at 21:25
  • You're right that there is no TTY involved (I've updated my explanation), but also note there is no race condition, and if systemd kills processes that users start, well then it is broken, but we already knew that right? – Greg A. Woods Mar 13 '20 at 21:34
  • I've mentioned the race condition because I had assumed that -t (force pseudotty) was used. But still, notice that a) </dev/null isn't needed -- just try ssh localhost 'realpath /dev/stdin &' and b) exec isn't needed: exec cmd & is absolutely the same as cmd &. – mosvy Mar 13 '20 at 23:31
  • Indeed, STDIN is already open on /dev/null, and yes I agree the exec is unnecessary. – Greg A. Woods Mar 13 '20 at 23:40

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.