Mike Pennington
Mike Pennington

Reputation: 43077

Script hangs while using Fabric's Connection.run() in the background

Overview

I'm trying to use python fabric to run an ssh command as root on a remote server.

The command: nohup ./foo &

foo is expected to command run for several days. I must be able to disassociate foo from fabric's remote ssh session, and put foo in the background.

The Fabric FAQ says you should use something like screen or tmux when you run your fabric script (which runs the backgrounded command). I tried that, but my fabric script still hung. foo is not hanging.

Question

How do I use fabric to run this command on a remote server without the script hanging: nohup ./foo &

Details

This is my script:

#!/bin/sh
# Credit: https://unix.stackexchange.com/a/20895/6766
if "true" : '''\'
    then
    exec "/nfs/it/network_python/$OSREL/bin/python" "$0" "$@"
    exit 127
fi
'''

from getpass import getpass
import os

from fabric import Connection, Config

assert os.geteuid()==0, "ERROR: Must run as root"

for host in ['host1.foo.local', 'host2.foo.local']:
    # Make an ssh connection to the host...
    conn = Connection(host)

    # The script always hangs at this line 
    result = conn.run('nohup ./foo &', warn=True, hide=True)

I always open a tmux session to run the aforementioned script in; even doing so, the script hangs when I get to conn.run(), above.

I'm running the script on a vanilla CentOS 6.5 VM; it runs under python 2.7.10 and fabric 2.1.

Upvotes: 0

Views: 1254

Answers (1)

Mike Pennington
Mike Pennington

Reputation: 43077

The Fabric FAQ is unclear... I thought the FAQ wanted tmux used on the local side when I executed the Fabric script.

The correct way to fix this problem is to replace nohup in the remote command, with screen -d -m <command>. Now I can run the whole script locally with no hangs (and I don't have to use tmux in the local term).

Explicitly, I have to rewrite the last line of my script in my question as:

    # Remove &, and nohup...
    result = conn.run('screen -d -m ./foo', warn=True, hide=True)

Upvotes: 2

Related Questions