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"]});
    1. // define command used to create the subprocess
    2. 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.

    1. /**
    2. * subprocess.ts
    3. */
    4. const fileNames = Deno.args;
    5. const p = Deno.run({
    6. cmd: [
    7. "deno",
    8. "run",
    9. "--allow-read",
    10. "https://deno.land/std@$STD_VERSION/examples/cat.ts",
    11. ...fileNames,
    12. ],
    13. });
    14. const { code } = await p.status();
    15. // Reading the outputs closes their pipes
    16. const rawOutput = await p.output();
    17. const rawError = await p.stderrOutput();
    18. if (code === 0) {
    19. await Deno.stdout.write(rawOutput);
    20. } else {
    21. const errorString = new TextDecoder().decode(rawError);
    22. console.log(errorString);
    23. }
    24. Deno.exit(code);

    When you run it:

    1. /**
    2. * subprocess_piping_to_file.ts
    3. */
    4. import {
    5. readableStreamFromReader,
    6. writableStreamFromWriter,
    7. } from "https://deno.land/std@$STD_VERSION/streams/conversion.ts";
    8. // create the file to attach the process to
    9. const file = await Deno.open("./process_output.txt", {
    10. read: true,
    11. write: true,
    12. create: true,
    13. });
    14. const fileWriter = await writableStreamFromWriter(file);
    15. // start the process
    16. const process = Deno.run({
    17. cmd: ["yes"],
    18. stdout: "piped",
    19. stderr: "piped",
    20. });
    21. // example of combining stdout and stderr while sending to a file
    22. const stdout = readableStreamFromReader(process.stdout);
    23. const stderr = readableStreamFromReader(process.stderr);
    24. const joined = mergeReadableStreams(stdout, stderr);
    25. // returns a promise that resolves when the process is killed/closed
    26. joined.pipeTo(fileWriter).then(() => console.log("pipe join done"));
    27. // manually stop process "yes" will never end on its own
    28. setTimeout(async () => {
    29. }, 100);

    Run it: