Forum

Send commands to background process

Hey there! I am looking for a way to send commands directly to a process running in background, started from Executor. Is this somehow implementable in the node itself with StandardInput / stdin?

I guess what I am asking for is basically the same what @zeos did here:

can you provide an example of such a process and what input to send and what to expect in return?

Sure! Here is a simple example of what I am trying to achieve, Supercollider should be installed on your system for this. Basically I am running the SC interpreter (sclang) via the Executor node and want to send the strings on the right one after the other - first one to start the synthesis server, then to generate a simple sine wave and the third to kill the sound.

SupercolliderInput.vl (12.1 KB)

Currently I’ve got a workaround set up with a local webserver run by a python script (which I am calling with the Executor node instead) that is opening sclang and forwards commands received as strings via HTTP POST to the process via stdin. The following is the code of this workaround, which I am trying to replace with a native solution in vvvv.

import subprocess
from subprocess import Popen
import sys
import time
from http.server import HTTPServer, BaseHTTPRequestHandler
import json

PORT = 8000

p = Popen(["sclang"], stdin=subprocess.PIPE, universal_newlines=True)

def run_command(command):
	print("running command: " + command)
	p.stdin.write(command)
	p.stdin.write('\x0c')
	p.stdin.flush()


# auf "Welcome to SuperCollider..."" warten
time.sleep(3.0)

class MyHandler(BaseHTTPRequestHandler):
	def do_POST(self):
		content_type = self.headers.get("Content-Type")
		content_length = int(self.headers.get("Content-Length"))
		body = self.rfile.read(content_length).decode("utf-8")

		if content_type == "application/json":
			data = json.loads(body)
			if type(data) == str:
				run_command(data)
			else:
				print("error: unknown json data:" + type(data) + " / " + body)
		else:
			run_command(body)

		# send 200 response
		self.send_response(200)
		# send response headers
		self.end_headers()
		# send the body of the response
		self.wfile.write(bytes("ok", "utf-8"))

httpd = HTTPServer(('localhost', 4444), MyHandler)
httpd.serve_forever()

As you can see it’s important to send an ascii return (’\x0c’) directly after the command, because that is the signal for SC to evaluate the command, like described here: Scripting sclang via external process - #4 by elgiano - Questions - scsynth

ok. i’ve added a “SendString” node for the Executor that you can use to send input to a running process like so:

grafik

3 Likes

Thaaaaaaanks!