1

I've written a script that generates a phylogentic tree with the ete3 package, the script runs on a headless server thus it must be launched with xvfb-run (per here).

I've setup the script to check (through a system call to ps) if it was called with xvfb. In the case where the python script is launched without xvfb-run (e.g. python script.py...), is there a straightforward way for me to kill the process and re-run it correctly (e.g. xvfb-run python script.py...) from within the original script call?

I've tried hacking something together with os.system() calls to ps, but I'm not having much luck. Does anyone have any suggestions?

Constantino
  • 2,243
  • 2
  • 24
  • 41

1 Answers1

2

I was able to put something together, just add the function check_xvfb() to the start of your script.

def check_xvfb():
    """
    Use of the ete3 library from the command line requires an X11 server
    which doesn't exist on this headless Ubuntu server.  One way around this
    is to use xvfb-run.  This function checks that the script was properly
    launched with xvfb-run; if not, it will relaunch it (with the same options)
    and then terminate the previously called script
                                                                                                                                           Parameters
    ----------                                                                                                                             none

    Returns
    -------
    none

    """

    # CHECK IF SCRIPT PROPERLY LAUNCHED
    # see http://stackoverflow.com/a/6550543/1153897 for explanation of 'cat'
    # grep -v ignores the ps -ef call since it'll match itself
    comm = 'ps -ef | grep xvfb-run | grep %s | grep -v grep | cat' %os.path.splitext(os.path.basename(sys.argv[0]))[0]
    output = subprocess.check_output(comm, shell=True)

    if not len(output): # script not called properly
        print 'script not called properly, retrying...'
        comm_run = 'xvfb-run ' + ' '.join(sys.argv)
        os.system(comm_run) # properly call script
        sys.exit(0)
    else:
        print 'script called properly!'
Constantino
  • 2,243
  • 2
  • 24
  • 41