20

I want to be able to take a command string, for example:

some/script --option="Quoted Option" -d --another-option 'Quoted Argument'

And parse it into something that I can send to child_process.spawn:

spawn("some/script", ["--option=\"Quoted Option\"", "-d", "--another-option", "Quoted Argument"])

All of the parsing libraries I've found (e.g. minimist, etc.) do too much here by parsing it into some kind of options object, etc. I basically want the equivalent of whatever Node does to create process.argv in the first place.

This seems like a frustrating hole in the native APIs since exec takes a string, but doesn't execute as safely as spawn. Right now I'm hacking around this by using:

spawn("/bin/sh", ["-c", commandString])

However, I don't want this to be tied to UNIX so strongly (ideally it'd work on Windows too). Halp?

4
  • It is not node.js that creates process.argv, but the shell interpreter you use. So it is system dependent. bash's interpretation will be different from that of Windows cmd. Commented May 6, 2014 at 9:50
  • @Michael: did you find any solution. I'm facing the same problem right now. Commented May 27, 2014 at 22:02
  • @Krasimir nope, never found a definitive answer. I'm still using /bin/sh for the time being. Commented May 28, 2014 at 5:34
  • If you're looking to split a command line sentence into args, then string-argv or spawn-args may be helpful. Commented Aug 1, 2020 at 18:14

2 Answers 2

27

Standard Method (no library)

You don't have to parse the command string into arguments, there's an option on child_process.spawn named shell.

options.shell

If true, runs command inside of a shell.
Uses /bin/sh on UNIX, and cmd.exe on Windows.

Example:

let command = `some_script --option="Quoted Option" -d --another-option 'Quoted Argument'`

let process = child_process.spawn(command, [], { shell: true })  // use `shell` option

process.stdout.on('data', (data) => {
  console.log(data)
})

process.stderr.on('data', (data) => {
  console.log(data)
})

process.on('close', (code) => {
  console.log(code)
})
Sign up to request clarification or add additional context in comments.

1 Comment

Still works in 2024! Perfect answer.
5

The minimist-string package might be just what you're looking for.

Here's some sample code that parses your sample string -

const ms = require('minimist-string')
const sampleString = 'some/script --option="Quoted Option" -d --another-option \'Quoted Argument\'';
const args = ms(sampleString);
console.dir(args)

This piece of code outputs this -

{
  _: [ 'some/script' ],
  option: 'Quoted Option',
  d: true,
  'another-option': 'Quoted Argument'
}

1 Comment

How can you then turn that data into a child_process command? If you turned those key/value pairs back into a string would you know that d needs 1 - instead of 2. Same with option.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.