Voer bash-commando uit in Node.js en krijg exit-code

Ik kan een bash-opdracht in node.js als volgt uitvoeren:

var sys = require('sys')
var exec = require('child_process').exec;
function puts(error, stdout, stderr) { sys.puts(stdout) }
exec("ls -la", function(err, stdout, stderr) {
  console.log(stdout);
});

Hoe krijg ik de afsluitcode van dat commando (ls -lain dit voorbeeld)? Ik heb geprobeerd te rennen

exec("ls -la", function(err, stdout, stderr) {
  exec("echo $?", function(err, stdout, stderr) {
    console.log(stdout);
  });
});

Dit geeft op de een of andere manier altijd 0 terug, ongeacht de afsluitcode van het vorige commando. Wat mis ik?


Antwoord 1, autoriteit 100%

Die 2 commando’s draaien in aparte shells.

Om de code te krijgen, zou je err.codemoeten kunnen controleren in je terugbelverzoek.

Als dat niet werkt, moet u een gebeurtenishandler exittoevoegen

bijv.

dir = exec("ls -la", function(err, stdout, stderr) {
  if (err) {
    // should have err.code here?  
  }
  console.log(stdout);
});
dir.on('exit', function (code) {
  // exit code is code
});

Antwoord 2, autoriteit 16%

Uit de documenten:

Als een callback-functie is opgegeven, wordt deze aangeroepen met de argumenten (error, stdout, stderr). Bij succes is Errornull. Bij een fout is Erroreen instantie van Fout. De eigenschap error.codeis de afsluitcode van het onderliggende proces, terwijl error.signalwordt ingesteld op het signaal dat het proces heeft beëindigd. Elke andere afsluitcode dan 0 wordt als een fout beschouwd.

Dus:

exec('...', function(error, stdout, stderr) {
  if (error) {
    console.log(error.code);
  }
});

Zou moeten werken.


Antwoord 3, autoriteit 8%

child_process.spawnSync()

Deze functie onthult de mooiste synchronisatie-interface: https://nodejs.org/api/child_process. html#child_process_child_process_spawnsync_command_args_options

Voorbeeld:

#!/usr/bin/env node
const child_process = require('child_process');
let out;
out = child_process.spawnSync('true');
console.log('status: ' + out.status);
console.log('stdout: ' + out.stdout.toString('utf8'));
console.log('stderr: ' + out.stderr.toString('utf8'));
console.log();
out = child_process.spawnSync('false');
console.log('status: ' + out.status);
console.log('stdout: ' + out.stdout.toString('utf8'));
console.log('stderr: ' + out.stderr.toString('utf8'));
console.log();
out = child_process.spawnSync('echo', ['abc']);
console.log('status: ' + out.status);
console.log('stdout: ' + out.stdout.toString('utf8'));
console.log('stderr: ' + out.stderr.toString('utf8'));
console.log();

Uitvoer:

status: 0
stdout: 
stderr: 
status: 1
stdout: 
stderr: 
status: 0
stdout: abc
stderr: 

Getest in Node.js v10.15.1, Ubuntu 19.10.


Antwoord 4, autoriteit 2%

In de knooppuntdocumentatie vond ik deze informatie voor de callback-functie:

Bij succes is de fout nul. Bij fout is fout een instantie van Fout. De eigenschap error.code is de afsluitcode van het onderliggende proces, terwijl error.signal wordt ingesteld op het signaal dat het proces heeft beëindigd. Elke andere afsluitcode dan 0 wordt als een fout beschouwd.


Antwoord 5, autoriteit 2%

Als iemand op zoek is naar een await/Promise-versie:

const exec = require('util').promisify(require('child_process').exec);
let out = await exec(`echo hello`).catch(e => e);
console.log(out.stdout); // outputs "hello"
console.log(out.code); // Note: `out.code` is *undefined* if successful (instead of 0).

Als het commando succesvol is, zal het een object uitvoeren zoals {stderr, stdout}. Als het een exit-code heeft die niet nul is, dan zal het een error-object uitvoeren met {stderr, stdout, code, killed, signal, cmd}en de gebruikelijke JavaScript Errorobjecteigenschappen zoals messageen stack.

Other episodes