Exec crashes Sketchup

I am having a issue where the following line opens a cmd prompt and Sketchup immediately closes. There is no crash report or anything it simply disappears. Putting it in a begin rescue block does not seem to help. My python file only contains a infinite loop to keep the window from closing.

exec("python test.py params")

I want to run a python script from Ruby. Am I misunderstanding how this method works?

[Edit]
system 'python test.py ' + params seems to work ok

I can reproduce it and it does what it is specified to do. Have you read the documentation:

(You don’t want to execute methods without knowing what they do?)

There is also some nice explanation here:

2 Likes

I myself usually use the %x string.

Ruby can do just about anything that Python can. Why would you wish to involve another scripting environment ?

The best way I have found to run python scripts and collect stderr and stdout (if you need to) is by using popen3. This is an example of what I use.

script = 'some_python_script.py ' + args
puts script

popen3(script) do |stdin, stdout, stderr|
  stdout.read.split("\n").each do |line|
    puts "[python] stdout: #{line}"
  end
  stderr.read.split("\n").each do |line|
    puts "[python] stderr: #{line}"
  end
end
puts  'Script completed.'
1 Like

I support many dcc’s not just Sketchup, The rest of them currently relay on python so our code base is built in python.

Thanks, this looks great.

But you must load the Open3 module from the standard library:

module Marsh
  module Plugin

    require "open3"
    
    Open3.popen3(script) {
      # code
    }

  end
end

The Open3 module is a double-duty library and mixin module. (There are 2 copies of each method, one for calling with qualification from outside, and an instance method copy for mixing into classes or modules, with include or extend. The example above shows that it has likely been included in a custom plugin class.)

1 Like

Is there anyway I can execute popen3 without showing the terminal? Currently It pops a terminal window that starts post process script and closes when the script is done. I would prefer that this step is silent and not noticed by the user.

Not on Windows. It has been like this like forever. There is a bug (in the Ruby Core) that prevents us from using Cscript.exe (or Wscript.exe) as the shell because Ruby hardcodes adding a “/c” parameter (which assumes the command shell will always be cmd.exe.) That is plain stupid, when Ruby allows setting the RUBYSHELL environment variable.

Anyway if you change RUBYSHELL (for SketchUp’s copy of ENV,) you’ll get an error, because Microsoft stupidly wrote Cscript.exe (and Wscript.exe) to choke on unknown parameters, rather than ignore them like cmd.exe does. (Ie, they do not recognize a “/c” parameter.)

The simpliest workaround has been to write a one-line batch command file with Ruby, and then execute it silently using the SketchUp API’s UI.openURL() method.

So see the Ruby docs on File class.

params = "/i /whatever"

cmdpath = "some/path/to/use"
Dir::chdir(cmdpath) {

  cmdfile = "runpyscript.bat"
  File::new(cmdfile,File::WRONLY|File::CREAT) {|file|
    file.puts("python test.py #{params}")
  } # the file is closed automatically
  Kernel.sleep(0.3) # let filesystem catch up
  UI.openURL(cmdfile) if File::exist?(cmdfile)

} # previous working dir is restored automatically