Schniz / cmd-ts

💻 A type-driven command line argument parser
https://cmd-ts.now.sh
MIT License
231 stars 24 forks source link

How to execute shell commands inside `handler`? #195

Open nikitavoloboev opened 1 year ago

nikitavoloboev commented 1 year ago

I tried doing this:

import { command, optional, positional, run, string } from "cmd-ts"
import { execa } from "execa"

const cmd = command({
  name: "gitty",
  description: "automate git",
  version: "0.0.1",
  args: {
    query: positional({ type: optional(string), displayName: "query" }),
  },
  handler: async (args) => {
      const { stdout } = await execa("echo", ["unicorns"])
      console.log(stdout)

  },
})

run(cmd, process.argv.slice(2))

But then if you try run it, you won't get echo unicorns as output.

If you run below code outside the handler:

      const { stdout } = await execa("echo", ["unicorns"])
      console.log(stdout)

It works as expected. Not sure why that happens or how to fix.

nikitavoloboev commented 1 year ago

repo where I am using cmd-ts: https://github.com/nikitavoloboev/gitty

code I want to make work is here

Schniz commented 1 year ago

What’s the console output then?

nikitavoloboev commented 1 year ago

It's empty.

image
Schniz commented 1 year ago

Very suspicious. I hope I will have some time to take a look. You are more than welcome to fork and add a test.

7frank commented 1 month ago

I think i might have a similar problem using bun shell instead of "execa"

running

const pwd= await $`pwd`.text()
console.log(pwd)

inside a "handler" will simply terminate the script and not output anything

A workaround is using a custom script.

function execShellCommand(cmd:string):Promise<string> {
  const exec = require('child_process').exec;
  return new Promise((resolve, reject) => {
   exec(cmd, (error:unknown, stdout:string, stderr:string) => {
    if (error) {
     console.warn(error);
    }
    resolve(stdout? stdout : stderr);
   });
  });
 }
const pwd=await execShellCommand(`pwd`)
console.log(pwd)