Search code examples
deno

How do I run an arbitrary shell command from Deno?


I want to run any arbitrary bash command from Deno, like I would with a child_process in Node. Is that possible in Deno?


Solution

  • Deno 1.28.0 added a new API to run a shell command: Deno.Command (--allow-run permission required)

    let cmd = new Deno.Command("echo", { args: ["hello world"] });
    let { code, stdout, stderr } = await cmd.output();
    // stdout & stderr are a Uint8Array
    console.log(new TextDecoder().decode(stdout)); // hello world
    

    More advanced usage:

    const command = new Deno.Command(Deno.execPath(), {
      args: [
        "eval",
        "console.log('Hello World')",
      ],
      stdin: "piped",
      stdout: "piped",
    });
    const child = command.spawn();
    
    // open a file and pipe the subprocess output to it.
    child.stdout.pipeTo(
      Deno.openSync("output", { write: true, create: true }).writable,
    );
    
    // manually close stdin
    child.stdin.close();
    const status = await child.status;
    
    const s = await c.status;
    console.log(s);
    

    This API replaced the deprecated Deno.run


    OLD ANSWER:

    In order to run a shell command, you have to use Deno.run, which requires --allow-run permissions.

    There's an ongoing discussion to use --allow-all instead for running a subprocess


    The following will output to stdout.

    // --allow-run
    const process = Deno.run({
      cmd: ["echo", "hello world"]
    });
    
    // Close to release Deno's resources associated with the process.
    // The process will continue to run after close(). To wait for it to
    // finish `await process.status()` or `await process.output()`.
    process.close();
    

    If you want to store the output, you'll have to set stdout/stderr to "piped"

    const process = Deno.run({
      cmd: ["echo", "hello world"], 
      stdout: "piped",
      stderr: "piped"
    });
    
    
    const output = await process.output() // "piped" must be set
    const outStr = new TextDecoder().decode(output);
    
    /* 
    const error = await p.stderrOutput();
    const errorStr = new TextDecoder().decode(error); 
    */
    
    process.close();