@SuppressWarnings("resource") // Do not close stdin 
	protected ExecInDrgn execInDrgn(String script) throws IOException {
		ResourceFile rf = Application.getModuleDataFile("TestResources", CORE);
		script = script.replace("$CORE", rf.getAbsolutePath());
		Path fp = Files.createTempFile("test", ".py");
		FileWriter fw = new FileWriter(fp.toFile());
		fw.write(script);
		fw.close();
		ProcessBuilder pb = new ProcessBuilder(pythonPath.toString(), "-c",
			rf.getAbsolutePath(), fp.toFile().getAbsolutePath());
		setPythonPath(pb);

		// If commands come from file, Python will quit after EOF.
		Msg.info(this, "outFile: " + outFile);
		Msg.info(this, "errFile: " + errFile);

		//pb.inheritIO();
		pb.redirectInput(ProcessBuilder.Redirect.PIPE);
		pb.redirectOutput(outFile.toFile());
		pb.redirectError(errFile.toFile());
		Process pyproc = pb.start();
		return new ExecInDrgn(pyproc, CompletableFuture.supplyAsync(() -> {
			try {
				if (!pyproc.waitFor(TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
					Msg.error(this, "Timed out waiting for Python");
					pyproc.destroyForcibly();
					pyproc.waitFor(TIMEOUT_SECONDS, TimeUnit.SECONDS);
					return new PythonResult(true, -1, Files.readString(outFile),
						Files.readString(errFile));
				}
				Msg.info(this, "Python exited with code " + pyproc.exitValue());
				return new PythonResult(false, pyproc.exitValue(), Files.readString(outFile),
					Files.readString(errFile));
			}
			catch (Exception e) {
				return ExceptionUtils.rethrow(e);
			}
			finally {
				pyproc.destroyForcibly();
			}
		}));
	}
Some snapshot likely to exceed the latest
Ghidra/Test/DebuggerIntegrationTest/src/test.slow/java/agent/drgn/rmi/AbstractDrgnTraceRmiTest.java