Reputation: 2027
Judging by the API docs, a Deno subprocess (an instance of Deno.Process
) can receive one of four stdin types, the same goes for stdout. However, there's no mention in the documentation as to how to pipe the output from one subprocess to the input of another. What I'm trying to achieve is akin to the basic UNIX pipe (oneProcess | another
) and then read the output of the second process in the pipeline. Simply running
const someProcess = Deno.run({
cmd: ["oneProcess firstParameter | another 2ndParameter"]
});
fails with an error of:
error: Uncaught NotFound: No such file or directory (os error 2)
because the first argument (string) is expected to be an executable.
How would one achieve this is Deno then, are we required to perhaps set "piped"
as both the output and input to the subprocesses (respectively) and then manually read and write data from one to another?
Upvotes: 10
Views: 3311
Reputation: 73
For anyone from the future where Deno.run()
is deprecated, here's one way to do it with Deno.Command()
(as of Deno 1.37.2). I took the same example as the accepted answer.
/*
How to 'echo "hello world" | md5sum' in Deno (1.37.2) with Deno.Command()
example.ts
*/
// our commands
const echo = new Deno.Command('echo', { args: ['hello world'], stdout: 'piped' }).outputSync()
const md5sum = new Deno.Command('md5sum', { stdin: 'piped', stdout: 'piped' }).spawn()
// pipe whatver our first stdout was to the next stdin
const writer = md5sum.stdin.getWriter()
// let Deno do the thing
await writer.write(echo.stdout)
await writer.ready
await writer.close()
// do whatever with the final stdout
const md5sum_out = await md5sum.output()
// there it is => 6f5902ac237024bdd0c176cb93063dc4
console.log('there it is => ', new TextDecoder().decode(md5sum_out.stdout))
// depending on the commands we might need this to not block Deno...
md5sum.unref()
Don't forget to run with the --allow-run
command but beware!
The --allow-run permission is required for creation of a subprocess. Be aware that subprocesses are not run in a Deno sandbox and therefore have the same permissions as if you were to run the command from the command line yourself.
deno run --allow-run example.ts
Upvotes: 6
Reputation: 40414
You're getting NotFound: no such file or directory
because the value passed to cmd
must be a path to the binary.
the first element needs to be a path to the binary
And onProcess | another
is not a binary.
To use a unix pipe |
you can run bash
and then write to stdin
.
const p = Deno.run({
cmd: ["bash"],
stdout: "piped",
stdin: "piped"
});
const encoder = new TextEncoder();
const decoder = new TextDecoder();
const command = "echo -n yes | md5sum";
await p.stdin.write(encoder.encode(command));
await p.stdin.close();
const output = await p.output()
p.close();
console.log(decoder.decode(output)); // a6105c0a611b41b08f1209506350279e
Upvotes: 10