mattvr
mattvr9mo ago

Read child process I/O

I want to write a simple Deno CLI script using Deno.Command or dx that can read output from a shell utility. For example, gum input --placeholder=\"Enter your name\" displays a small text input, which I want to read the user input into Deno. - If I use a Deno.Command stdout: "inherit", then Deno doesn't have access to the stdout stream (containing the user name), just the file signal. - So I tried stdout: "piped" and piping the streams – but then the terminal hangs and displays nothing. Does this use look right?:
const cmd = new Deno.Command("gum", {
args: [
"input",
"--placeholder=\"Enter your name\"",
],
stdin: "piped",
stdout: "piped",
stderr: "piped",
})
const process = cmd.spawn()
Deno.stdin.readable.pipeTo(process.stdin);
process.stdout.pipeTo(Deno.stdout.writable);
process.stderr.pipeTo(Deno.stderr.writable);
const cmd = new Deno.Command("gum", {
args: [
"input",
"--placeholder=\"Enter your name\"",
],
stdin: "piped",
stdout: "piped",
stderr: "piped",
})
const process = cmd.spawn()
Deno.stdin.readable.pipeTo(process.stdin);
process.stdout.pipeTo(Deno.stdout.writable);
process.stderr.pipeTo(Deno.stderr.writable);
2 Replies
Deno AI Helper
Deno AI Helper9mo ago
When using Deno.Command to spawn a subprocess and interact with its I/O streams, it's important to understand how the stdin, stdout, and stderr options work. According to the documentation, if you set stdout to "piped", you can access the output of the subprocess as a ReadableStream. However, if you set stdout to "inherit", the subprocess will inherit the standard output of the parent process, and you won't be able to programmatically read the output because it's directly written to the terminal. In your case, you want to read the output from the gum utility, so setting stdout to "piped" is correct. However, there are a few things to consider in your code snippet: 1. You are piping Deno.stdin.readable to process.stdin, which means you're trying to forward the input from the Deno process to the gum utility. If gum is expecting input from the user, this might not be necessary unless you want to programmatically send input to gum. 2. You are piping process.stdout to Deno.stdout.writable and process.stderr to Deno.stderr.writable. This should forward the output and error streams from gum to the Deno process's standard output and error streams, respectively. 3. It's important to close the stdin of the subprocess if you're done sending input. According to the documentation, if stdin is set to "piped", the stdin WritableStream needs to be closed manually. Here's a revised version of your code snippet that takes these points into account: ```ts const cmd = new Deno.Command("gum", { args: [ "input", "--placeholder="Enter your name"", ], stdout: "piped", // We want to read the output programmatically stderr: "piped", // We want to read the error output programmatically }); const process =
Deno AI Helper
Deno AI Helper9mo ago
cmd.spawn(); // Assuming we don't need to send input to gum, we don't pipe Deno.stdin to process.stdin // If you do need to send input, uncomment the following line and ensure to close process.stdin when done // Deno.stdin.readable.pipeTo(process.stdin); // Forward the output of gum to Deno's stdout const stdoutPromise = process.stdout.pipeTo(Deno.stdout.writable); // Forward the error output of gum to Deno's stderr const stderrPromise = process.stderr.pipeTo(Deno.stderr.writable); // Wait for both piping operations to complete await Promise.all([stdoutPromise, stderrPromise]); // Get the exit status of the subprocess const status = await process.status; console.log("Process exited with code:", status.code); `` Remember to handle the case where gum` might not produce