CaptainProg
CaptainProg

Reputation: 5690

Close Python script, then immediately relaunch

I'm using Python (Vizard) to launch a virtual reality environment on a laptop remotely. I need to do this remotely, because the laptop is closed and being worn in a backpack by the user who is also wearing a head mounted display. I am able to open a network connection and send commands which cause a virtual reality environment to load on the laptop, but I'm not able to close the environment without closing Vizard completely.

In order to launch, I add a network, like this:

myNetwork = viz.addNetwork('computer_name')

I then wait for a network message using a network event callback:

def onNetwork(e):
    loadWorld(e.preferences)

viz.callback(viz.NETWORK_EVENT, onNetwork)

def loadWorld(preferences):
    <<...>>

So, this works nicely, and boots the player into the virtual reality environment with the preferences specified in preferences. But if I send another message over the network, the new world is superposed on top of the old world, and there doesn't seem to be a useful method for closing the virtual reality environment in a tidy manner.

Since I can't deconstruct the virtual reality environment in a decent way, it seems better to reboot the whole program from the beginning. There is a command in Vizard, viz.quit(), but if I insert this before the loadWorld function call, the program stops running completely and never reaches loadWorld. So, I wonder if there's another way I could do this: have the program close, but have the whole script running in a loop so that when the program closes, it immediately relaunches again.

The question: how do I tell a Python script to close and deallocate all resources, but then to immediately relaunch itself afterwards?

Upvotes: 3

Views: 558

Answers (2)

s3ni0r
s3ni0r

Reputation: 471

The answer above won't close open file objects and descriptors, see os.execv(), so a clean up should be done before executing os.execv(), as stated in the python documentation you can use sys.stdout.flush() or os.fsync() to flush open file objects and descriptors.

Upvotes: 0

MikeRixWolfe
MikeRixWolfe

Reputation: 430

Not sure about vizard, but if you just need to relaunch a script, this is one way to do it.

import os, sys

#stuff

def restart():
    args = sys.argv[:]  # get shallow copy of running script args
    args.insert(0, sys.executable)  # give it the executable
    os.execv(sys.executable, args)  # execute the script with current args, effectively relaunching it, can modify args above to change how it relaunches

Calling restart() will relaunch the script with the same args.

I can confirm this works for a plain old python script in a *nix environment with executable permissions and a shebang at it's head, hopefully this helps with your vizard problem

Upvotes: 1

Related Questions