5

I faced an urge to run different scripts simultaneously on different servers. (+/- 2 seconds not a problem) The condition is to launch the scripts by the invocation from the primary server, and NOT by the Cron schedule. I tried SSH, but this way I must wait till the script finishes running on the remote server and only then drop the session. I'm looking for an alternative way, that allows to start the script on remote server without waiting for its end. P.S. - I'm not using CLI in my use case, but an external script invocation app, that triggers the script on the primary server. Thanks.

  • What Linux distro is this? – George Udosen Dec 22 '17 at 18:48
  • @George - CentOS 6.5 and CentOS 7.xx – faceless Dec 22 '17 at 18:51
  • 2
    Maybe Ansible will work for you? – DopeGhoti Dec 22 '17 at 19:12
  • @DopeGhoti - external soft is problematic. I was hoping to find a Linux based solution. Tried screen, but don't think it is purely suitable. – faceless Dec 22 '17 at 19:17
  • @Fox - I must kill the SSH session on the primary server after triggering the script on the secondary. And I need this script to be finished. – faceless Dec 22 '17 at 19:36
5

GNU screen will allow you to execute remote jobs without staying connected to the server, except on systems where systemd kills all processes upon logout1. Specifically, you can use:

#!/bin/sh
ssh server1 screen -d -m command1
ssh server2 screen -d -m command2
# ...

Each local ssh session terminates immediately after launching the remote screen process, which in turn exits as soon as the executed command finishes. You can suffix each ssh line with & to make the connections in parallel.

Excerpt from the manual, screen(1):

-d -m Start screen in "detached" mode. This creates a new session but doesn't attach to it. This is useful for system startup scripts.


1 If you are on a system that uses systemd configured with killUserProcesses=yes, you will need to replace screen with systemd-run --user --scope screen.

  • Doesn’t CentOS 7 use systemd? – Nothingismagick Dec 23 '17 at 23:21
  • 1
    @Nothingismagick Possibly. But "systems where systemd kills all processes upon logout" is a subset of "systems that use systemd" — specifically the subset that are configure with killUserProcesses=yes. There is a workaround (that I just added as a footnote), but I always just change the setting – Fox Dec 23 '17 at 23:35
5

Use ‘& disown’ to send the command to a sub shell that is then disowned. Use nohup if you need process tracking. Below I used the sleep binary wrapped in a time call to give quick feedback in the console about what is going on.

time sleep 5

The shell is blocking, so you won’t be able to nicely exit the session.

time sleep 5 &

Is subshelled, so exiting will still kill the sleep command.

time nohup sleep 5 &

This subshells the nohup, so you’re doing better because of logging, but a sub shell will still be attached to the shell that created it and therefore it and it’s processes will be destroyed when the session ends. You really just need to disown it:

#!/bin/bash

nohup sleep 500 & disown
pid=$!
echo $pid > /tmp/time.pid
exit 0
  • sounds like it may partially work for me. I must put all this in a script (cannot send the stand alone commands), thus the script will get the PID, and the disowning contents will not be able to catch it. Is there a way to disown a PID of the script by the commands it contains? – faceless Dec 22 '17 at 19:32
  • No, within a script the $! Reference will always be to the command previously disowned, not the hosting script. – Nothingismagick Dec 22 '17 at 19:34
  • byobu would work as it can be set up in the secondary and disconnected from the primary and the script would still be running – George Udosen Dec 22 '17 at 19:47
  • Yes it should work that way (as long as you separate with new lines. :) – Nothingismagick Dec 22 '17 at 20:00

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.