Creating a subprocess
- Deno is capable of spawning a subprocess via Deno.run.
- permission is required to spawn a subprocess.
- Spawned subprocesses do not run in a security sandbox.
- Communicate with the subprocess via the , stdout and streams.
- Use a specific shell by providing its path/name and its string input switch,
e.g.
Deno.run({cmd: ["bash", "-c", "ls -la"]});
// define command used to create the subprocess
const cmd = ["cmd", "/c", "echo hello"];
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.
/**
* subprocess.ts
*/
const fileNames = Deno.args;
const p = Deno.run({
cmd: [
"deno",
"run",
"--allow-read",
"https://deno.land/std@$STD_VERSION/examples/cat.ts",
...fileNames,
],
});
const { code } = await p.status();
// Reading the outputs closes their pipes
const rawOutput = await p.output();
const rawError = await p.stderrOutput();
if (code === 0) {
await Deno.stdout.write(rawOutput);
} else {
const errorString = new TextDecoder().decode(rawError);
console.log(errorString);
}
Deno.exit(code);
When you run it:
/**
* subprocess_piping_to_file.ts
*/
import {
readableStreamFromReader,
writableStreamFromWriter,
} from "https://deno.land/std@$STD_VERSION/streams/conversion.ts";
// create the file to attach the process to
const file = await Deno.open("./process_output.txt", {
read: true,
write: true,
create: true,
});
const fileWriter = await writableStreamFromWriter(file);
// start the process
const process = Deno.run({
cmd: ["yes"],
stdout: "piped",
stderr: "piped",
});
// example of combining stdout and stderr while sending to a file
const stdout = readableStreamFromReader(process.stdout);
const stderr = readableStreamFromReader(process.stderr);
const joined = mergeReadableStreams(stdout, stderr);
// returns a promise that resolves when the process is killed/closed
joined.pipeTo(fileWriter).then(() => console.log("pipe join done"));
// manually stop process "yes" will never end on its own
setTimeout(async () => {
}, 100);
Run it: