Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to do multiple commands? #42

Open
buildgreatthings opened this issue Jan 16, 2019 · 3 comments
Open

How to do multiple commands? #42

buildgreatthings opened this issue Jan 16, 2019 · 3 comments

Comments

@buildgreatthings
Copy link

I want a spawn process to do multiple commands in one line.

The terminal line looks like this: cd ~/folder && node test.js >> ./test.log

What's the correct way to do this?

My code is directly from the tutorial:

	let command = "cd ~/folder && node test.js >> ./test.log"
	logger.info("Spawning: " + command)
	var job = spawn(command);
	var childProcess = job.childProcess;

	logger.verbose('[spawn] childProcess.pid: ', childProcess.pid);
	childProcess.stdout.on('data', function (data) {
	    logger.verbose('[spawn] ' + childProcess.pid + ' stdout: ', data.toString());
	});
	childProcess.stderr.on('data', function (data) {
	    logger.verbose('[spawn] ' + childProcess.pid + ' stderr: ', data.toString());
	});
	 
	job.then(function () {
        logger.verbose('[spawn] ' + childProcess.pid + ' done!');
    })
    .catch(function (err) {
        logger.error('[spawn] ' + childProcess.pid + ' ERROR: ', err);
    });
@casha1995
Copy link

i had the same problem but this issue on stack over flow helped me , i hope it can help you too
https://stackoverflow.com/questions/35004492/node-child-process-spawn-multiple-commands
@https://stackoverflow.com/users/1783916/jan-j%c5%afna
From Node.js v6 you can specify a shell option in spawn method which will run command using shell and thus it is possible to chain commands using spawn method.

For example this:

var spawn = require('child_process').spawn;
var child = spawn('ls && ls && ls', {
  shell: true
});
child.stderr.on('data', function (data) {
  console.error("STDERR:", data.toString());
});
child.stdout.on('data', function (data) {
  console.log("STDOUT:", data.toString());
});
child.on('exit', function (exitCode) {
  console.log("Child exited with code: " + exitCode);
});

i hope this is the issue you're talking about

@RadoslavMarinov
Copy link

What about passing arguments to each separate command? Like 'ls && ls && ls', [[ '-lh', '/usr' ],[ '-lh', '/usr' ]] ?

@binki
Copy link

binki commented Oct 23, 2020

@RadoslavMarinov That is building up a shell string. Doing this properly is error-prone and platform-dependent.

Instead, you should individually invoke all of those programs, using logic in your program to proceed or fail. For example, you might call ls multiple times like the following:

call-ls-multiple-times.js:

#!/usr/bin/env node
const spawn = require('cross-spawn');

(async () => {
  const invocations = [
    ['ls', '-lh', '/usr'],
    ['ls', '-la', '/usr'],
  ];
  for (const [program, ...args] of invocations) {
    await spawnAsync(program, args, {
      stdio: 'inherit',
    });
  }
})();

async function spawnAsync(program, args, options) {
  options = (Array.isArray(args) ? options : args) || {};
  args = Array.isArray(args) ? args : [];
  const code = await new Promise((resolve, reject) => {
    const cp = spawn(program, args, options);
    cp.on('error', ex => reject(ex));
    cp.on('close', code => resolve(code));
  });
  if (code !== 0) {
    throw new Error(`${program}${args.length ? ` ${JSON.stringify(args)}` : ''} exited with non-zero code ${code}.`);
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants