spawnsync node example child_process child node.js stdin detect

example - node.js: ¿Cómo detectar una secuencia estándar stdin?



spawn vs exec node (4)

Tengo un script / servidor node.js que lee algo de entrada de stdin cuando se inicia. Sin embargo, a veces no hay datos para pasar. Esto es problemático porque parece que en este caso no se llaman los data ni los eventos end . ¿Cómo puedo detectar cuando este es el caso en el código node.js?

Me gustaría evitar tener que agregar caracteres "finales" especiales al final de la entrada, para no molestar al cliente. El código asociado está abajo:

var newHTML = ''''; var gfm = spawn(__dirname + ''/node_modules/docter/bin/github-flavored-markdown.rb''); process.stdin.on(''data'', function(chunk){ gfm.stdin.write(chunk); }); process.stdin.on(''end'', function(){ gfm.stdin.end(); }); gfm.stdout.on(''data'', function(data) { newHTML += data; }); gfm.on(''exit'',function(ecode){ socket.emit(''newContent'', newHTML); }); process.stdin.resume();


Algo que puedes hacer es hacer que tu aplicación acepte un argumento como -s que hace que se lea desde stdin.

Eso es lo que hace la herramienta CLI de LiveScript:

-s, --stdin read stdin


Creo que lo que puede estar sucediendo es que no estás dando un impulso por completo.

El ejemplo de Øystein Steimler muestra cómo alimentar / dev / null en su aplicación:

nodo pipe.js </ dev / null

Sin embargo, nunca se aborda cuando no se transmite la entrada estándar a la aplicación. Simplemente ejecutando node pipe.js no se node pipe.js porque todavía está esperando la entrada estándar .

Puede probar esto usted mismo con otros programas de Unix, por ejemplo cat

Intenta ejecutar esto:

cat < /dev/null

Ahora intente simplemente ejecutando:

cat

No sale porque está esperando la entrada estándar. Puede escribir en el terminal y enviar al programa presionando enter. Todavía no saldrá (y esperará más entrada) hasta que reciba el EOF que puede hacer con ctrl + d


El evento end detecta un flujo STDIN vacío o no.

Este simple script stdin.js demuestra que:

process.stdin.on( ''data'', function(data) { console.log( data ) } ); process.stdin.on( ''end'', function() { console.log( ''EOF'' ) } );

Diferentes escenarios:

$ echo test | node stdin.js <Buffer 74 65 73 74 0a> EOF $ echo -n | node stdin.js EOF $ node stdin.js < /dev/null EOF $

Este script pipe.js demuestra que el uso de pipe para un proceso hijo generado funciona muy bien:

var spawn = require(''child_process'').spawn; var cat = spawn( ''/bin/cat'' ); cat.stdout.on( ''data'', function(data) { console.log( data ) } ); cat.stdout.on( ''end'', function() { console.log( ''EOF'' ) } ); process.stdin.pipe(cat.stdin);

Como se esperaba:

$ echo test | node pipe.js <Buffer 74 65 73 74 0a> EOF $ echo -n | node pipe.js EOF $ node pipe.js < /dev/null EOF $


La forma en que funciona stdin , lo que quieres no es directamente posible.

Como han señalado otros, el evento end nunca se activará sin algo como < /dev/null para generar ese EOF . De lo contrario, el programa espera a que el terminal envíe un ^D

Un enfoque alternativo que podría funcionar para usted es establecer un tiempo de espera que caduque después de un corto período de tiempo si no hay actividad en la stdin . Esto es menos que ideal, pero funciona:

function handleData(chunk) { //clearTimeout(timeout); gfm.stdin.write(chunk); } function handleEnd() { //clearTimeout(timeout); gfm.stdin.end(); } function handleTimeout() { process.stdin.removeListener(''data'', handleData); process.stdin.removeListener(''end'', handleEnd); // Do whatever special handling is needed here. gfm.stdin.end(); } const timeoutMilliseconds = 100; process.stdin.on(''data'', handleData); process.stdin.on(''end'', handleEnd); const timeout = setTimeout(handleTimeout, timeoutMilliseconds); // You could skip the rest of this code if you just add `clearTimeout(timeout)` // to the body of `handleData` and `handleEnd` but that would call `clearTimeout` excessively. function stopTimeout() { process.stdin.removeListener(''data'', stopTimeout) process.stdin.removeListener(''end'', stopTimeout); clearTimeout(timeout); } process.stdin.on(''data'', stopTimeout); process.stdin.on(''end'', stopTimeout);