2020-09-08 16:00:18 +02:00
|
|
|
extends Node
|
|
|
|
class_name Shell
|
|
|
|
|
|
|
|
var _cwd
|
2020-09-08 16:36:52 +02:00
|
|
|
var _fake_editor
|
2020-09-08 16:00:18 +02:00
|
|
|
|
2020-09-08 22:16:18 +02:00
|
|
|
signal output(text)
|
|
|
|
|
2020-09-08 16:00:18 +02:00
|
|
|
func _init():
|
2020-09-09 11:48:42 +02:00
|
|
|
_cwd = game.tmp_prefix
|
2020-09-08 16:00:18 +02:00
|
|
|
|
|
|
|
func cd(dir):
|
|
|
|
_cwd = dir
|
|
|
|
|
|
|
|
# Run a shell command given as a string. Run this if you're interested in the
|
|
|
|
# output of the command.
|
|
|
|
func run(command):
|
2020-09-08 20:13:49 +02:00
|
|
|
var debug = false
|
2020-09-08 16:00:18 +02:00
|
|
|
|
|
|
|
if debug:
|
|
|
|
print("$ %s" % command)
|
|
|
|
|
|
|
|
var env = {}
|
2020-09-08 16:36:52 +02:00
|
|
|
env["EDITOR"] = _fake_editor
|
2020-09-08 16:00:18 +02:00
|
|
|
|
|
|
|
var hacky_command = ""
|
|
|
|
for variable in env:
|
|
|
|
hacky_command += "export %s='%s';" % [variable, env[variable]]
|
|
|
|
hacky_command += "cd '%s';" % _cwd
|
|
|
|
hacky_command += command
|
|
|
|
|
2020-09-09 11:01:30 +02:00
|
|
|
var output = _exec(_shell_binary(), ["-c", hacky_command])
|
2020-09-08 16:00:18 +02:00
|
|
|
|
|
|
|
if debug:
|
|
|
|
print(output)
|
|
|
|
|
|
|
|
return output
|
2020-09-09 11:01:30 +02:00
|
|
|
|
|
|
|
func _shell_binary():
|
|
|
|
var os = OS.get_name()
|
|
|
|
|
|
|
|
if os == "X11":
|
2020-09-09 11:48:42 +02:00
|
|
|
return "sh"
|
2020-09-09 11:01:30 +02:00
|
|
|
elif os == "Windows":
|
2020-09-09 11:48:42 +02:00
|
|
|
return "sh.exe"
|
2020-09-09 11:01:30 +02:00
|
|
|
else:
|
|
|
|
push_error("Unsupported OS")
|
|
|
|
get_tree().quit()
|
2020-09-08 16:46:12 +02:00
|
|
|
|
2020-09-08 22:16:18 +02:00
|
|
|
var _t
|
|
|
|
func run_async(command):
|
|
|
|
_t = Thread.new()
|
|
|
|
_t.start(self, "run_async_thread", command)
|
|
|
|
|
|
|
|
func run_async_thread(command):
|
|
|
|
var port = 1000 + (randi() % 1000)
|
|
|
|
var s = TCP_Server.new()
|
|
|
|
s.listen(port)
|
|
|
|
OS.execute("ncat", ["127.0.0.1", str(port), "-c", command], false, [], true)
|
|
|
|
while not s.is_connection_available():
|
|
|
|
pass
|
|
|
|
var c = s.take_connection()
|
|
|
|
print("ok")
|
|
|
|
while c.get_status() == StreamPeerTCP.STATUS_CONNECTED:
|
|
|
|
var available = c.get_available_bytes()
|
|
|
|
if available > 0:
|
|
|
|
var data = c.get_utf8_string(available)
|
|
|
|
emit_signal("output", data)
|
|
|
|
print(data)
|
|
|
|
c.disconnect_from_host()
|
|
|
|
s.stop()
|
|
|
|
|
2020-09-08 16:46:12 +02:00
|
|
|
# Run a simple command with arguments, blocking, using OS.execute.
|
|
|
|
func _exec(command, args=[]):
|
|
|
|
var debug = false
|
|
|
|
|
|
|
|
if debug:
|
|
|
|
print("exec: %s [%s]" % [command, PoolStringArray(args).join(", ")])
|
|
|
|
|
|
|
|
var output = []
|
2020-09-08 20:26:14 +02:00
|
|
|
var exit_code = OS.execute(command, args, true, output, true)
|
2020-09-08 16:46:12 +02:00
|
|
|
output = output[0]
|
|
|
|
|
2020-09-08 20:26:14 +02:00
|
|
|
if exit_code != 0:
|
|
|
|
push_error("OS.execute failed: %s [%s] Output: %s" % [command, PoolStringArray(args).join(", "), output])
|
|
|
|
|
2020-09-08 16:46:12 +02:00
|
|
|
if debug:
|
|
|
|
print(output)
|
|
|
|
|
|
|
|
return output
|