-
Hi! I'm trying to implement a websocket server which executes shell commands and streams the output over a WebSocket. I've got it working using With const p = spawn("some-command", ["arg1", "arg2"]);
p.on("close", () => {
ws.close(10003, "program exited");
});
p.stderr.on("data", (data) => {
ws.send(
JSON.stringify({
type: "output",
source: "stderr",
data: new TextDecoder().decode(data),
} as OutputMessage),
);
}); but I can't figure out an equivalent for const cmd = Bun.spawn(["some-command", "arg1", "arg2"], {
onExit: () => {
ws.close(10003, 'program exited');
},
stderr: "pipe",
});
for await (const line of cmd.stderr) {
// "line" here isn't actually a line, it's the entire stderr.
ws.send(
JSON.stringify({
type: "output",
source: "stdout",
data: new TextDecoder().decode(line),
} as OutputMessage),
);
} In the Bun case, Is this just something that is expected and I should be using the node library or should I be able to achieve the same behaviour via Bun? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
@itmecho I just came across your post! In case you're still looking for an answer two weeks later, here it is :) When you iterate over const cmd = Bun.spawn(["some-command", "arg1", "arg2"], {
stderr: "pipe",
onExit: () => {
ws.close(10003, 'program exited');
},
});
const reader = cmd.stderr.pipeThrough(new TextDecoderStream()).getReader();
let remainder = '';
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
const lines = (remainder + value).split('\n');
remainder = lines.pop()!;
for (const line of lines) {
ws.send(
JSON.stringify({
type: 'output',
source: 'stdout',
data: line,
} as OutputMessage),
);
}
} |
Beta Was this translation helpful? Give feedback.
@itmecho I just came across your post! In case you're still looking for an answer two weeks later, here it is :)
When you iterate over
cmd.stderr
, you get back a buffer chunk, which may be a line, multiple lines, half a line, you don't know.... Therefore, you need to implement a basic line reader like this: