2

I want to use node.js to spawn echo $(python --version), if I put this into my terminal it works no problem, I get something like

Python 2.7.12

But if I use the following code:

var spawn = require('child_process').spawn
var child = spawn('echo', ['$(python --version)'])
child.stdout.on('data', function(b){
    console.log(b.toString())
})

I just get the string literal echo'ed back to me:

$(python --version)

How to I escape the argument to spawn properly so I get the correct output.

Edit: I specifically want to use spawn, and echo, I would like to know if there is a solution to properly escape the spawn argument...

Eoin Murray
  • 1,935
  • 3
  • 22
  • 34
  • 1
    It's because `$()` is a bash operator, and child_process is using sh instead of bash. See https://stackoverflow.com/questions/32952410/using-bash-with-node-js-child-process-using-the-shell-option-fails for setting your shell while using child_process. – Tennyson H Aug 09 '16 at 21:05
  • When you run `echo $(python --version)`, in a shell, the echo is pretty much useless. Since `python --version` doesn't output anything to stdout, you are just running `python --version` and then running `echo` with no arguments. It is the equivalent of doing `$(python --version); echo`, which means the echo just prints a newline character. – Paul Aug 09 '16 at 21:27

2 Answers2

1

This should help you out.

var exec = require('child_process').exec;
exec('python --version', function(error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
  console.log('exec error: ' + error);
}
});

Edited as requested in the comment:

var exec = require('child_process').exec;
exec('echo "Output goes here"', function(error, stdout) { //Replace echo with any other command.
    console.log(stdout);
});

Output: Output goes here.

May want to check this: How do I escape a string for a shell command in node?

Community
  • 1
  • 1
Karma Doe
  • 114
  • 12
  • I specifically want to use 'echo' and not call python itself...perhaps I should have pointed that out in the question, the question is more about escaping strings in spawn than this specific problem – Eoin Murray Aug 09 '16 at 20:57
1

I realize that I am quite late to the party here, but as I was looking for an answer for this myself:

I believe the issue is that the spawn command does not run in a shell by default (see Node.js Documentation). I think that Node.js does this to protect you, by escaping all shell metacharaters, which is what you were experiencing. If you set the shell option to true, it will work as desired, like this:

require('child_process').spawn('echo', ['$(python --version)'], {shell: true, stdio: 'inherit'});

NB: Setting stdio to inherit from the parent process means that you don't have to log stdout yourself :)