Analyse la sortie de l'a engendré node.js processus enfant ligne par ligne
J'ai un PhantomJS/CasperJS script sur lequel je suis en cours d'exécution à partir de l'intérieur d'un node.js script à l'aide de process.spawn()
. Depuis CasperJS ne prend pas en charge require()
ing modules, je suis en train d'imprimer les commandes de CasperJS à stdout
puis de les lire à partir de mon node.js script à l'aide de spawn.stdout.on('data', function(data) {});
, pour faire des choses comme ajouter des objets à redis/mangouste (alambiquée, oui, mais semble plus simple que d'installer un service web pour cela...) Le CasperJS script exécute une série de commandes et crée de, disons, 20 captures d'écran qui doivent être ajoutés à ma base de données.
Cependant, je ne peux pas comprendre comment briser le data
variable (un Buffer
?) dans les lignes... j'ai essayé de le convertir à une chaîne et puis en faisant un remplacement, j'ai essayé de faire spawn.stdout.setEncoding('utf8');
mais rien ne semble fonctionner...
Voici ce que j'ai droit maintenant
var spawn = require('child_process').spawn;
var bin = "casperjs"
//googlelinks.js is the example given at http://casperjs.org/#quickstart
var args = ['scripts/googlelinks.js'];
var cspr = spawn(bin, args);
//cspr.stdout.setEncoding('utf8');
cspr.stdout.on('data', function (data) {
var buff = new Buffer(data);
console.log("foo: " + buff.toString('utf8'));
});
cspr.stderr.on('data', function (data) {
data += '';
console.log(data.replace("\n", "\nstderr: "));
});
cspr.on('exit', function (code) {
console.log('child process exited with code ' + code);
process.exit(code);
});
https://gist.github.com/2131204
- Est-ce la meilleure approche? Il semble que le
stdout.on('data')
événement se déclenche selon taille de la mémoire tampon, pas nécessairement de nouvelles lignes. Est-ce vrai?
Vous devez vous connecter pour publier un commentaire.
Essayez ceci:
Noter que les "données" de l'événement ne serait pas nécessairement briser uniformément entre les lignes de sortie, de sorte qu'une seule ligne peut s'étendre sur plusieurs événements de données.
\r
est en option à partir de la regex caractère spécial?
donc ce code devrait fonctionner sur UNIX et Windows; c'est faire l'expression régulière global (.../g
) qui a été probablement critiques ici. L'appel à "remplacer" dans votre exemple de code utilisé une simple chaîne de caractères qui est converti dans un non-global regex, donc, vous avez probablement juste deux lignes au lieu de tous.En fait, j'ai écrit un Nœud de la bibliothèque pour exactement cet effet, il est appelé flux de splitter et vous pouvez le trouver sur Github: samcday/stream-splitter.
La bibliothèque offre un
Stream
vous pouvez diriger votre casper stdout dans, avec un séparateur (dans votre cas, \n), et il émet soignétoken
événements, un pour chaque ligne, il est divisé à partir de l'entréeStream
. La mise en œuvre interne pour cela est très simple, et la plupart des délégués de la magie à substack/node-tampons qui signifie qu'il n'est pas inutileBuffer
allocations/copies.Ajoutant à maerics de réponse, ce qui ne permet pas de traiter correctement les cas où seule une partie de la ligne est alimentée en données de vidage (eux vous donnera la première partie et la deuxième partie de la ligne individuellement, comme deux lignes distinctes.)
utilisation:
J'ai trouvé une jolie manière de le faire avec de la pure nœud, ce qui semble bien fonctionner:
Vous pouvez donner à ceci un essai. Il ignore toutes les lignes vides ou vides de nouveaux sauts de ligne.
Vieux trucs, mais toujours utile...
J'ai fait un flux de Transformer la sous-classe à cette fin.
Voir https://stackoverflow.com/a/59400367/4861714