简体   繁体   中英

Make Popen wait for first command to finish then start next

I'm trying to run a program and feed the program a script as such:

subprocess.Popen(['X:\\apps\\Nuke6.1v5\\Nuke6.1.exe', '-t', 'X:\\apps\\Scripts\NUKE\\nukeExternalControl\\server.py'])

My problem is that it takes the program a few seconds to finish launching. So while its starting up the program Popen runs the next command and of course because the program is not up and running is errors out. So my question is how do I tell Popen to wait for the first application to run THEN execute the next part of Popen.. any takers??

UPDATE

    import nukeExternalControl.client

    np = subprocess.Popen(['X:\\apps\\Nuke6.1v5\\Nuke6.1.exe', '-t', 'X:\\apps\\Scripts\NUKE\\nukeExternalControl\\server.py'])


    print "Starting Nuke Server"

    conn = nukeExternalControl.client.NukeConnection()
    nuke = conn.nuke

    print "execute commands"

    nuke.root().knob('first_frame').setValue(1)
    nuke.root().knob('last_frame').setValue(10)

    read = nuke.createNode('CheckerBoard2')
    textFrame = nuke.createNode('Text')
    textShotName = nuke.createNode('Text')
    reformat = nuke.createNode('Reformat')
    write = nuke.createNode('Write')

SOLUTION

So! Thanks to jdi the problem has been sovled! Props to him as he has stuck this problem out with me for quite some time... thanks so much!

ANSWER:

I needed to use time.sleep() after the Popen command because my server was not waiting for nuke to start before communicating to it.

After glancing over the readme for this nuke module, I get the sense that you might be confused about what is actually required to use it.

subprocess.Popen(['X:\\\\apps\\\\Nuke6.1v5\\\\Nuke6.1.exe', '-t', 'X:\\\\apps\\\\Scripts\\NUKE\\\\nukeExternalControl\\\\server.py'])

... This line (which I assume you are actually assigning to a variable and either blocking on it, or checking its status), is what is required to start a non-gui based server with Nuke. Nuke being a python interpreter can run a python script via nuke -t <script.py> , hence you are using it to start your server process. This will block, and wait for you to use your client class to communicate.

What seems to be missing from your question is more context about how you are exactly trying to run this server/client configuration. If you are attempting to do both parts in the same script, then you would need to start the server process as you are doing, then maybe sleep for a second (the server process starts pretty quickly), and then run the client code that makes the connection.

Update

Realistically there are two ways to start your server process, as very plainly outlined in the readme:

To start a command sever whenever Nuke is launched, add the following lines
to your Nuke menu.py:
---------------------------
import nukeExternalControl.server
nukeExternalControl.server.nuke_command_server()
---------------------------

This is something you would put in your nuke menu.py file, or manually start this with a running Nuke application. Your application will now be running a server process and allow clients to connect.

If you dont want to have to use a GUI license and keep it running to server connections, then you use the other method from the command line X:\\apps\\Nuke6.1v5\\Nuke6.1.exe -t X:\\apps\\Scripts\\NUKE\\nukeExternalControl\\server.py , which starts a terminal-based server. There is NO reason I can think of that you need to be using subprocess to start the server in your script when they give you a method for starting it already.

Solution

After a lengthy conversation with the OP, it turns out that what he wanted to do was what the first part of my answer suggested. He has a standalone script that wants to do something using Nuke's python interpreter (completely headless without the Nuke GUI app). Using this 3rd party module , he wants to start the script in a subprocess that will act as a server to the nuke terminal. He will then proceed in his code to communicate with it using the client class (he is self hosting a server process and sorta round-robin communicating with it.

The solution to his problem was that he needed to time.sleep(2) right after the Popen that starts his server.py . Waiting a few seconds for the server to completely start allowed the client to successfully connect.

And yes, he owes me a beer now.

If the thing you're reffering to when you say "next command/thing" is 'X:\\\\apps\\\\Scripts\\NUKE\\\\nukeExternalControl\\\\server.py' , then you're quite confused. That's an command line argument passed to nuke.exe (the same way as C:\\ is passed when you execute dir C:\\ ).

There's simply no way to control what nuke.exe does from the python side... you have to check in your server.py that the exe is finished "booting".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM