Exec: stdout „live“ anzeigen

Lesezeit: 6 Minuten

mraveys Benutzeravatar
mravey

Ich habe dieses einfache Skript:

var exec = require('child_process').exec;

exec('coffee -cw my_file.coffee', function(error, stdout, stderr) {
    console.log(stdout);
});

wo ich einfach einen Befehl ausführe, um eine Kaffee-Skriptdatei zu kompilieren. Aber stdout wird nie in der Konsole angezeigt, da der Befehl nie endet (wegen der Option -w von Coffee). Wenn ich den Befehl direkt von der Konsole aus ausführe, erhalte ich eine Meldung wie diese:

18:05:59 - compiled my_file.coffee

Meine Frage ist: Ist es möglich, diese Nachrichten mit der node.js-Exec anzuzeigen? Wenn ja, wie? !

  • Ich bin hierher gekommen, um Stdout aus der ausführbaren Python-Datei zu erfassen. Beachten Sie, dass alle unten genannten Schritte funktionieren, Sie müssen Python jedoch mit der Option „-u“ ausführen, um die Ausgabe ungepuffert zu machen und dadurch Live-Updates zu erhalten.

    – Andy

    5. November 2017 um 18:36 Uhr

Pooria Azimis Benutzeravatar
Pooria Azimi

Nicht verwenden exec. Verwenden spawn Das ist ein EventEmmiter Objekt. Dann können Sie zuhören stdout/stderr Veranstaltungen (spawn.stdout.on('data',callback..)) wie sie geschehen.

Aus der NodeJS-Dokumentation:

var spawn = require('child_process').spawn,
    ls    = spawn('ls', ['-lh', '/usr']);

ls.stdout.on('data', function (data) {
  console.log('stdout: ' + data.toString());
});

ls.stderr.on('data', function (data) {
  console.log('stderr: ' + data.toString());
});

ls.on('exit', function (code) {
  console.log('child process exited with code ' + code.toString());
});

exec Puffert die Ausgabe und gibt sie normalerweise zurück, wenn die Ausführung des Befehls abgeschlossen ist.

  • Sehr schön. Zu Ihrer Information: Das Rückrufargument „data“ für stdout/stderr-Ereignisse ist ein Puffer, also rufen Sie ihn mit .toString() auf.

    – SergeL

    9. Mai 2014 um 14:01

  • Für diejenigen unter Ihnen, die Spawn unter Windows nicht zum Laufen bringen können, schauen Sie sich diese großartige Antwort an.

    – tomekwi

    27. August 2014 um 8:33

  • exec ist zumindest in letzter Zeit auch ein EventEmitter.

    – Nikolay Tsenkov

    27. Juni 2015 um 15:50 Uhr

  • Beachten Sie auch, dass der Rückruf nicht immer dann aufgerufen wird, wenn das Programm einen Zeilenumbruch ausgibt. Wenn Sie „Ereignisse“ vom untergeordneten Prozess empfangen möchten, muss dieser Prozess den Puffer leeren (flush(stdout); in C), um Ereignisse in Node.js auszulösen.

    – Julian F. Weinert

    20. März 2016 um 1:18

  • +1 dafür, dass exec auch ein EventEmitter ist. Ich habe 2 Stunden damit verbracht, meinen String in ein args-Array umzuwandeln (sehr lange und komplizierte ffmpeg-Befehlszeile). Nur um herauszufinden, dass ich das nicht wirklich brauchte.

    – tote Gespräche

    4. April 2016 um 13:34

Benutzeravatar von Nathanael Smith
Nathanael Smith

exec gibt außerdem ein ChildProcess-Objekt zurück, das ein EventEmitter ist.

var exec = require('child_process').exec;
var coffeeProcess = exec('coffee -cw my_file.coffee');

coffeeProcess.stdout.on('data', function(data) {
    console.log(data); 
});

ODER pipe die Standardausgabe des untergeordneten Prozesses in die Standardausgabe des Hauptprozesses.

coffeeProcess.stdout.pipe(process.stdout);

ODER erben Sie stdio mit spawn

spawn('coffee -cw my_file.coffee', { stdio: 'inherit' });

  • Es sieht so aus, als ob dies durch einfaches Verwenden vereinfacht werden kann pipe: coffeeProcess.stdout.pipe(process.stdout);

    – Eric Freese

    19. August 2015 um 15:00 Uhr

  • Der Kommentar von @EricFreese ist das, wonach ich gesucht habe, weil ich die Zeichenersetzungsfunktion von stdout nutzen wollte (Winkelmesser in einem Knotenskript nutzen).

    – LoremIpsum

    31. Okt. 2016 um 11:00 Uhr

  • Einfacher: spawn(cmd, argv, { stdio: 'inherit' }). Sehen nodejs.org/api/child_process.html#child_process_options_stdio für verschiedene Beispiele.

    – Morgan Touverey Quilling

    30. März 2017 um 14:39

  • +1 für den Verwendungsvorschlag von @MorganTouvereyQuilling spawn mit stdio: 'inherit'. Es erzeugt eine genauere Ausgabe als exec und Rohrleitungen stdout/stderrzum Beispiel bei der Anzeige der Fortschrittsinformationen von a git clone.

    – Livven

    18. April 2017 um 15:56 Uhr

Livvens Benutzeravatar
Livven

Es gibt bereits mehrere Antworten, aber keine davon erwähnt den besten (und einfachsten) Weg, dies zu tun, nämlich die Verwendung spawn und das { stdio: 'inherit' } Möglichkeit. Es scheint die genaueste Ausgabe zu liefern, beispielsweise wenn die Fortschrittsinformationen von a angezeigt werden git clone.

Gehen Sie einfach so vor:

var spawn = require('child_process').spawn;

spawn('coffee', ['-cw', 'my_file.coffee'], { stdio: 'inherit' });

Dank geht an @MorganTouvereyQuilling für den Hinweis in diesem Kommentar.

  • Ich habe festgestellt, dass, wenn der Unterprozess formatierte Ausgaben wie farbigen Text verwendet, stdio: "inherit" behält diese Formatierung bei child.stdout.pipe(process.stdout) nicht.

    – Rikki Gibson

    21. September 2017 um 19:59 Uhr

  • Dadurch bleibt die Ausgabe selbst bei Prozessen mit komplexer Ausgabe wie den Fortschrittsbalken bei NPM-Installationen perfekt erhalten. Eindrucksvoll!

    – Dave Koo

    10. Juni 2018 um 18:17 Uhr

  • Warum ist dies nicht die akzeptierte Antwort? Es war das einzige, das bei mir funktioniert hat, und es sind nur zwei verdammte Zeilen!!!

    – Lincoln

    23. März 2019 um 20:56 Uhr

  • Dieser Tipp war hilfreich beim Ausführen einiger Symfony-Befehlszeilenanwendungen, die Fortschrittsbalken verwenden. Beifall.

    – Halbstopp

    16. Juli 2019 um 16:41 Uhr

  • Dies sollte die akzeptierte Antwort sein – die einzige Lösung, die eine perfekte Ausgabedarstellung beibehält Und es ist das einfachste? ja bitte

    – evnp

    31. März 2020 um 16:38

Benutzeravatar von Tyler Liu
Tyler Liu

Inspiriert durch Nathanael Smiths Antwort und Eric Freeses Kommentar könnte es so einfach sein wie:

var exec = require('child_process').exec;
exec('coffee -cw my_file.coffee').stdout.pipe(process.stdout);

Benutzeravatar von Kevin Teljeur
Kevin Teljeur

Ich möchte nur ein kleines Problem bei der Ausgabe der Pufferzeichenfolgen aus einem erzeugten Prozess mit hinzufügen console.log() besteht darin, dass Zeilenumbrüche hinzugefügt werden, die die erzeugte Prozessausgabe auf zusätzliche Zeilen verteilen können. Wenn Sie ausgeben stdout oder stderr mit process.stdout.write() anstatt console.log()dann erhalten Sie die Konsolenausgabe des erzeugten Prozesses „wie sie ist“.

Ich habe diese Lösung hier gesehen: Node.js: Auf Konsole ohne nachgestellten Zeilenumbruch drucken?

Ich hoffe, das hilft jemandem, der die obige Lösung verwendet (die sich hervorragend für die Live-Ausgabe eignet, auch wenn sie aus der Dokumentation stammt).

  • Für eine noch genauere Ausgabe verwenden spawn(command, args, { stdio: 'inherit' })wie von @MorganTouvereyQuilling hier vorgeschlagen: stackoverflow.com/questions/10232192/…

    – Livven

    18. April 2017 um 15:59 Uhr


Benutzeravatar von General Grievance
Allgemeine Beschwerde

Ich fand es hilfreich, meinen Dienstprogrammen, die dies tun, ein benutzerdefiniertes Exec-Skript hinzuzufügen.

utilities.js

const { exec } = require('child_process')

module.exports.exec = (command) => {
  const process = exec(command)
  
  process.stdout.on('data', (data) => {
    console.log('stdout: ' + data.toString())
  })
  
  process.stderr.on('data', (data) => {
    console.log('stderr: ' + data.toString())
  })
  
  process.on('exit', (code) => {
    console.log('child process exited with code ' + code.toString())
  })
}

app.js

const { exec } = require('./utilities.js')
    
exec('coffee -cw my_file.coffee')

  • Für eine noch genauere Ausgabe verwenden spawn(command, args, { stdio: 'inherit' })wie von @MorganTouvereyQuilling hier vorgeschlagen: stackoverflow.com/questions/10232192/…

    – Livven

    18. April 2017 um 15:59 Uhr


Tongfas Benutzeravatar
Tongfa

Nachdem ich alle anderen Antworten durchgesehen hatte, kam ich zu folgendem Ergebnis:

function oldSchoolMakeBuild(cb) {
    var makeProcess = exec('make -C ./oldSchoolMakeBuild',
         function (error, stdout, stderr) {
             stderr && console.error(stderr);
             cb(error);
        });
    makeProcess.stdout.on('data', function(data) {
        process.stdout.write('oldSchoolMakeBuild: '+ data);
    });
}

Manchmal data wird aus mehreren Zeilen bestehen, also oldSchoolMakeBuild Die Kopfzeile erscheint einmal für mehrere Zeilen. Aber das hat mich nicht genug gestört, um es zu ändern.

1454610cookie-checkExec: stdout „live“ anzeigen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy