Skip to content

Readline

[Estable: 2 - Estable]

Estable: 2 Estabilidad: 2 - Estable

Código fuente: lib/readline.js

El módulo node:readline proporciona una interfaz para leer datos de un flujo Readable (como process.stdin) una línea a la vez.

Para usar las API basadas en promesas:

js
import * as readline from 'node:readline/promises';
js
const readline = require('node:readline/promises');

Para usar las API de callback y síncronas:

js
import * as readline from 'node:readline';
js
const readline = require('node:readline');

El siguiente ejemplo simple ilustra el uso básico del módulo node:readline.

js
import * as readline from 'node:readline/promises';
import { stdin as input, stdout as output } from 'node:process';

const rl = readline.createInterface({ input, output });

const answer = await rl.question('¿Qué opinas de Node.js? ');

console.log(`Gracias por tus valiosos comentarios: ${answer}`);

rl.close();
js
const readline = require('node:readline');
const { stdin: input, stdout: output } = require('node:process');

const rl = readline.createInterface({ input, output });

rl.question('¿Qué opinas de Node.js? ', (answer) => {
  // TODO: Registrar la respuesta en una base de datos
  console.log(`Gracias por tus valiosos comentarios: ${answer}`);

  rl.close();
});

Una vez que se invoca este código, la aplicación Node.js no terminará hasta que se cierre readline.Interface porque la interfaz espera a que se reciban datos en el flujo input.

Clase: InterfaceConstructor

Agregado en: v0.1.104

Las instancias de la clase InterfaceConstructor se construyen utilizando el método readlinePromises.createInterface() o readline.createInterface(). Cada instancia está asociada con un único flujo input Readable y un único flujo output Writable. El flujo output se utiliza para imprimir indicaciones para la entrada del usuario que llega al flujo input y se lee de él.

Evento: 'close'

Añadido en: v0.1.98

El evento 'close' se emite cuando ocurre una de las siguientes situaciones:

  • Se llama al método rl.close() y la instancia InterfaceConstructor ha renunciado al control sobre los flujos input y output;
  • El flujo input recibe su evento 'end';
  • El flujo input recibe + para indicar el final de la transmisión (EOT);
  • El flujo input recibe + para indicar SIGINT y no hay ningún detector de eventos 'SIGINT' registrado en la instancia InterfaceConstructor.

La función de escucha se llama sin pasar ningún argumento.

La instancia InterfaceConstructor termina una vez que se emite el evento 'close'.

Evento: 'line'

Añadido en: v0.1.98

El evento 'line' se emite cada vez que el flujo input recibe una entrada de fin de línea (\n, \r o \r\n). Esto suele ocurrir cuando el usuario presiona o .

El evento 'line' también se emite si se han leído nuevos datos de un flujo y ese flujo termina sin un marcador final de fin de línea.

La función de escucha se llama con una cadena que contiene la única línea de entrada recibida.

js
rl.on('line', (input) => {
  console.log(`Recibido: ${input}`);
});

Evento: 'history'

Añadido en: v15.8.0, v14.18.0

El evento 'history' se emite cada vez que el array de historial ha cambiado.

La función de escucha se llama con un array que contiene el array de historial. Reflejará todos los cambios, líneas añadidas y líneas eliminadas debido a historySize y removeHistoryDuplicates.

El propósito principal es permitir que un detector de eventos persista el historial. También es posible que el detector de eventos cambie el objeto del historial. Esto podría ser útil para evitar que ciertas líneas se añadan al historial, como una contraseña.

js
rl.on('history', (history) => {
  console.log(`Recibido: ${history}`);
});

Evento: 'pause'

Añadido en: v0.7.5

El evento 'pause' se emite cuando ocurre una de las siguientes situaciones:

  • El flujo input está en pausa.
  • El flujo input no está en pausa y recibe el evento 'SIGCONT'. (Consulte los eventos 'SIGTSTP' y 'SIGCONT'.)

La función de escucha se llama sin pasar ningún argumento.

js
rl.on('pause', () => {
  console.log('Readline pausado.');
});

Evento: 'resume'

Agregado en: v0.7.5

El evento 'resume' se emite cada vez que se reanuda el flujo input.

La función de escucha se llama sin pasar ningún argumento.

js
rl.on('resume', () => {
  console.log('Readline reanudado.');
});

Evento: 'SIGCONT'

Agregado en: v0.7.5

El evento 'SIGCONT' se emite cuando un proceso de Node.js previamente movido al segundo plano usando + (es decir, SIGTSTP) se devuelve al primer plano usando fg(1p).

Si el flujo input se pausó antes de la solicitud SIGTSTP, este evento no se emitirá.

La función de escucha se invoca sin pasar ningún argumento.

js
rl.on('SIGCONT', () => {
  // `prompt` reanudará automáticamente el flujo
  rl.prompt();
});

El evento 'SIGCONT' no es compatible con Windows.

Evento: 'SIGINT'

Agregado en: v0.3.0

El evento 'SIGINT' se emite cada vez que el flujo input recibe una entrada , conocida típicamente como SIGINT. Si no hay listeners del evento 'SIGINT' registrados cuando el flujo input recibe un SIGINT, el evento 'pause' será emitido.

La función de escucha se invoca sin pasar ningún argumento.

js
rl.on('SIGINT', () => {
  rl.question('¿Está seguro de que quiere salir? ', (answer) => {
    if (answer.match(/^y(es)?$/i)) rl.pause();
  });
});

Evento: 'SIGTSTP'

Agregado en: v0.7.5

El evento 'SIGTSTP' se emite cuando el flujo input recibe una entrada +, normalmente conocida como SIGTSTP. Si no hay listeners del evento 'SIGTSTP' registrados cuando el flujo input recibe un SIGTSTP, el proceso de Node.js se enviará al segundo plano.

Cuando el programa se reanuda usando fg(1p), los eventos 'pause' y 'SIGCONT' se emitirán. Estos se pueden usar para reanudar el flujo input.

Los eventos 'pause' y 'SIGCONT' no se emitirán si el input se pausó antes de que el proceso se enviara al segundo plano.

La función de escucha se invoca sin pasar ningún argumento.

js
rl.on('SIGTSTP', () => {
  // Esto anulará SIGTSTP e impedirá que el programa se vaya al
  // segundo plano.
  console.log('Atrapado SIGTSTP.');
});

El evento 'SIGTSTP' no es compatible con Windows.

rl.close()

Agregado en: v0.1.98

El método rl.close() cierra la instancia InterfaceConstructor y renuncia al control sobre los flujos input y output. Cuando se llama, se emitirá el evento 'close'.

Llamar a rl.close() no detiene inmediatamente la emisión de otros eventos (incluido 'line') por parte de la instancia InterfaceConstructor.

rl.pause()

Agregado en: v0.3.4

El método rl.pause() pausa el flujo input, permitiendo que se reanude más tarde si es necesario.

Llamar a rl.pause() no pausa inmediatamente la emisión de otros eventos (incluido 'line') por parte de la instancia InterfaceConstructor.

rl.prompt([preserveCursor])

Agregado en: v0.1.98

  • preserveCursor <boolean> Si es true, evita que la posición del cursor se restablezca a 0.

El método rl.prompt() escribe el prompt configurado de las instancias InterfaceConstructor en una nueva línea en output para proporcionar al usuario una nueva ubicación en la que proporcionar la entrada.

Cuando se llama, rl.prompt() reanudará el flujo input si ha sido pausado.

Si el InterfaceConstructor se creó con output establecido en null o undefined, el prompt no se escribe.

rl.resume()

Agregado en: v0.3.4

El método rl.resume() reanuda el flujo input si ha sido pausado.

rl.setPrompt(prompt)

Agregado en: v0.1.98

El método rl.setPrompt() establece el prompt que se escribirá en output cada vez que se llame a rl.prompt().

rl.getPrompt()

Agregado en: v15.3.0, v14.17.0

  • Devuelve: <string> la cadena de prompt actual

El método rl.getPrompt() devuelve el prompt actual utilizado por rl.prompt().

rl.write(data[, key])

Agregado en: v0.1.98

El método rl.write() escribirá data o una secuencia de teclas identificada por key en la output. El argumento key solo se admite si output es un terminal de texto TTY. Consulte Combinaciones de teclas TTY para obtener una lista de combinaciones de teclas.

Si se especifica key, se ignora data.

Cuando se llama, rl.write() reanudará el flujo input si ha sido pausado.

Si el InterfaceConstructor se creó con output establecido en null o undefined, no se escriben data y key.

js
rl.write('¡Borra esto!');
// Simula Ctrl+U para borrar la línea escrita anteriormente
rl.write(null, { ctrl: true, name: 'u' });

El método rl.write() escribirá los datos en la Interface readline input como si fueran proporcionados por el usuario.

rl[Symbol.asyncIterator]()

[Historial]

VersiónCambios
v11.14.0, v10.17.0El soporte para Symbol.asyncIterator ya no es experimental.
v11.4.0, v10.16.0Añadido en: v11.4.0, v10.16.0

Crea un objeto AsyncIterator que itera a través de cada línea en el flujo de entrada como una cadena. Este método permite la iteración asíncrona de objetos InterfaceConstructor a través de bucles for await...of.

Los errores en el flujo de entrada no se reenvían.

Si el bucle se termina con break, throw o return, se llamará a rl.close(). En otras palabras, iterar sobre un InterfaceConstructor siempre consumirá el flujo de entrada por completo.

El rendimiento no está a la par con la API de eventos 'line' tradicional. Utilice 'line' en su lugar para aplicaciones sensibles al rendimiento.

js
async function processLineByLine() {
  const rl = readline.createInterface({
    // ...
  });

  for await (const line of rl) {
    // Cada línea en la entrada de readline estará disponible sucesivamente aquí como
    // `line`.
  }
}

readline.createInterface() comenzará a consumir el flujo de entrada una vez invocado. Tener operaciones asíncronas entre la creación de la interfaz y la iteración asíncrona puede resultar en líneas perdidas.

rl.line

[Historial]

VersiónCambios
v15.8.0, v14.18.0El valor siempre será una cadena, nunca indefinido.
v0.1.98Añadido en: v0.1.98

Los datos de entrada actuales que están siendo procesados por node.

Esto se puede utilizar al recopilar la entrada de un flujo TTY para recuperar el valor actual que se ha procesado hasta el momento, antes de que se emita el evento line. Una vez que se ha emitido el evento line, esta propiedad será una cadena vacía.

Tenga en cuenta que modificar el valor durante el tiempo de ejecución de la instancia puede tener consecuencias no deseadas si rl.cursor tampoco está controlado.

Si no está utilizando un flujo TTY para la entrada, utilice el evento 'line'.

Un posible caso de uso sería el siguiente:

js
const values = ['lorem ipsum', 'dolor sit amet'];
const rl = readline.createInterface(process.stdin);
const showResults = debounce(() => {
  console.log(
    '\n',
    values.filter((val) => val.startsWith(rl.line)).join(' '),
  );
}, 300);
process.stdin.on('keypress', (c, k) => {
  showResults();
});

rl.cursor

Añadido en: v0.1.98

La posición del cursor relativa a rl.line.

Esto rastreará dónde aterriza el cursor actual en la cadena de entrada, al leer la entrada de un flujo TTY. La posición del cursor determina la porción de la cadena de entrada que se modificará a medida que se procesa la entrada, así como la columna donde se representará el cursor del terminal.

rl.getCursorPos()

Añadido en: v13.5.0, v12.16.0

  • Devuelve: <Object>
    • rows <number> la fila del prompt donde se encuentra actualmente el cursor
    • cols <number> la columna de la pantalla donde se encuentra actualmente el cursor

Devuelve la posición real del cursor en relación con el prompt de entrada + la cadena. Las cadenas de entrada largas (que se ajustan), así como los prompts de varias líneas, se incluyen en los cálculos.

API de Promesas

Añadido en: v17.0.0

[Stable: 1 - Experimental]

Stable: 1 Estabilidad: 1 - Experimental

Clase: readlinePromises.Interface

Añadido en: v17.0.0

Las instancias de la clase readlinePromises.Interface se construyen utilizando el método readlinePromises.createInterface(). Cada instancia está asociada con un solo flujo input Readable y un solo flujo output Writable. El flujo output se utiliza para imprimir prompts para la entrada del usuario que llega y se lee desde el flujo input.

rl.question(query[, options])

Agregado en: v17.0.0

  • query <string> Una declaración o consulta para escribir en output, antepuesta al prompt.

  • options <Object>

    • signal <AbortSignal> Permite opcionalmente que question() se cancele usando una AbortSignal.
  • Devuelve: <Promise> Una promesa que se cumple con la entrada del usuario en respuesta a la query.

El método rl.question() muestra la query escribiéndola en la output, espera a que se proporcione la entrada del usuario en input, luego invoca la función callback pasando la entrada proporcionada como el primer argumento.

Cuando se llama, rl.question() reanudará el flujo input si se ha pausado.

Si readlinePromises.Interface se creó con output establecido en null o undefined, la query no se escribe.

Si se llama a la pregunta después de rl.close(), devuelve una promesa rechazada.

Ejemplo de uso:

js
const answer = await rl.question('¿Cuál es tu comida favorita? ');
console.log(`Oh, así que tu comida favorita es ${answer}`);

Usando una AbortSignal para cancelar una pregunta.

js
const signal = AbortSignal.timeout(10_000);

signal.addEventListener('abort', () => {
  console.log('La pregunta de la comida se agotó');
}, { once: true });

const answer = await rl.question('¿Cuál es tu comida favorita? ', { signal });
console.log(`Oh, así que tu comida favorita es ${answer}`);

Clase: readlinePromises.Readline

Agregado en: v17.0.0

new readlinePromises.Readline(stream[, options])

Agregado en: v17.0.0

rl.clearLine(dir)

Agregado en: v17.0.0

  • dir <integer>

    • -1: a la izquierda del cursor
    • 1: a la derecha del cursor
    • 0: la línea completa
  • Devuelve: this

El método rl.clearLine() agrega a la lista interna de acciones pendientes una acción que borra la línea actual del stream asociado en una dirección especificada identificada por dir. Llama a rl.commit() para ver el efecto de este método, a menos que se haya pasado autoCommit: true al constructor.

rl.clearScreenDown()

Agregado en: v17.0.0

  • Devuelve: this

El método rl.clearScreenDown() agrega a la lista interna de acciones pendientes una acción que borra el stream asociado desde la posición actual del cursor hacia abajo. Llama a rl.commit() para ver el efecto de este método, a menos que se haya pasado autoCommit: true al constructor.

rl.commit()

Agregado en: v17.0.0

El método rl.commit() envía todas las acciones pendientes al stream asociado y borra la lista interna de acciones pendientes.

rl.cursorTo(x[, y])

Agregado en: v17.0.0

El método rl.cursorTo() agrega a la lista interna de acciones pendientes una acción que mueve el cursor a la posición especificada en el stream asociado. Llama a rl.commit() para ver el efecto de este método, a menos que se haya pasado autoCommit: true al constructor.

rl.moveCursor(dx, dy)

Agregado en: v17.0.0

El método rl.moveCursor() agrega a la lista interna de acciones pendientes una acción que mueve el cursor relativamente a su posición actual en el stream asociado. Llama a rl.commit() para ver el efecto de este método, a menos que se haya pasado autoCommit: true al constructor.

rl.rollback()

Agregado en: v17.0.0

  • Devuelve: this

El método rl.rollback borra la lista interna de acciones pendientes sin enviarla al stream asociado.

readlinePromises.createInterface(options)

Agregado en: v17.0.0

  • options <Object>

    • input <stream.Readable> El stream Readable para escuchar. Esta opción es obligatoria.
    • output <stream.Writable> El stream Writable para escribir los datos de readline.
    • completer <Function> Una función opcional utilizada para la autocompletación con Tab.
    • terminal <boolean> true si los streams input y output deben tratarse como un TTY, y se deben escribir códigos de escape ANSI/VT100. Predeterminado: verificar isTTY en el stream output al momento de la instanciación.
    • history <string[]> Lista inicial de líneas del historial. Esta opción tiene sentido solo si terminal está configurado como true por el usuario o por una verificación output interna, de lo contrario, el mecanismo de almacenamiento en caché del historial no se inicializa en absoluto. Predeterminado: [].
    • historySize <number> Número máximo de líneas de historial retenidas. Para deshabilitar el historial, establezca este valor en 0. Esta opción tiene sentido solo si terminal está configurado como true por el usuario o por una verificación output interna, de lo contrario, el mecanismo de almacenamiento en caché del historial no se inicializa en absoluto. Predeterminado: 30.
    • removeHistoryDuplicates <boolean> Si es true, cuando una nueva línea de entrada agregada a la lista del historial duplica una anterior, esto elimina la línea anterior de la lista. Predeterminado: false.
    • prompt <string> La cadena de prompt para usar. Predeterminado: '\> '.
    • crlfDelay <number> Si el retraso entre \r y \n excede crlfDelay milisegundos, tanto \r como \n se tratarán como entradas de fin de línea separadas. crlfDelay se convertirá a un número no menor que 100. Se puede establecer en Infinity, en cuyo caso \r seguido de \n siempre se considerará una sola nueva línea (lo cual puede ser razonable para leer archivos con el delimitador de línea \r\n). Predeterminado: 100.
    • escapeCodeTimeout <number> La duración que readlinePromises esperará por un carácter (al leer una secuencia de teclas ambigua en milisegundos, una que puede formar una secuencia de teclas completa usando la entrada leída hasta ahora y puede tomar entrada adicional para completar una secuencia de teclas más larga). Predeterminado: 500.
    • tabSize <integer> El número de espacios a los que equivale una tabulación (mínimo 1). Predeterminado: 8.
  • Devuelve: <readlinePromises.Interface>

El método readlinePromises.createInterface() crea una nueva instancia de readlinePromises.Interface.

js
import { createInterface } from 'node:readline/promises';
import { stdin, stdout } from 'node:process';
const rl = createInterface({
  input: stdin,
  output: stdout,
});
js
const { createInterface } = require('node:readline/promises');
const rl = createInterface({
  input: process.stdin,
  output: process.stdout,
});

Una vez que se crea la instancia de readlinePromises.Interface, el caso más común es escuchar el evento 'line':

js
rl.on('line', (line) => {
  console.log(`Received: ${line}`);
});

Si terminal es true para esta instancia, entonces el stream output obtendrá la mejor compatibilidad si define una propiedad output.columns y emite un evento 'resize' en el output si o cuando las columnas cambien (process.stdout hace esto automáticamente cuando es un TTY).

Uso de la función completer

La función completer toma la línea actual ingresada por el usuario como un argumento y devuelve un Array con 2 entradas:

  • Un Array con entradas coincidentes para la finalización.
  • La subcadena que se utilizó para la coincidencia.

Por ejemplo: [[substr1, substr2, ...], originalsubstring].

js
function completer(line) {
  const completions = '.help .error .exit .quit .q'.split(' ');
  const hits = completions.filter((c) => c.startsWith(line));
  // Show all completions if none found
  return [hits.length ? hits : completions, line];
}

La función completer también puede devolver un <Promise> o ser asíncrona:

js
async function completer(linePartial) {
  await someAsyncWork();
  return [['123'], linePartial];
}

API de Callback

Agregado en: v0.1.104

Clase: readline.Interface

[Historial]

VersiónCambios
v17.0.0La clase readline.Interface ahora hereda de Interface.
v0.1.104Agregado en: v0.1.104

Las instancias de la clase readline.Interface se construyen utilizando el método readline.createInterface(). Cada instancia está asociada con un único flujo input Readable y un único flujo output Writable. El flujo output se utiliza para imprimir mensajes para la entrada del usuario que llega en el flujo input y se lee desde él.

rl.question(query[, options], callback)

Agregado en: v0.3.3

  • query <string> Una declaración o consulta para escribir en output, antepuesta al mensaje.

  • options <Object>

    • signal <AbortSignal> Opcionalmente, permite cancelar question() usando un AbortController.
  • callback <Function> Una función de callback que se invoca con la entrada del usuario en respuesta a la query.

El método rl.question() muestra la query escribiéndola en la output, espera a que se proporcione la entrada del usuario en input, luego invoca la función callback pasando la entrada proporcionada como el primer argumento.

Cuando se llama, rl.question() reanudará el flujo input si se ha pausado.

Si el readline.Interface se creó con output establecido en null o undefined, la query no se escribe.

La función callback pasada a rl.question() no sigue el patrón típico de aceptar un objeto Error o null como el primer argumento. Se llama al callback con la respuesta proporcionada como el único argumento.

Se generará un error si se llama a rl.question() después de rl.close().

Ejemplo de uso:

js
rl.question('¿Cuál es tu comida favorita? ', (answer) => {
  console.log(`Ah, entonces tu comida favorita es ${answer}`);
});

Usando un AbortController para cancelar una pregunta.

js
const ac = new AbortController();
const signal = ac.signal;

rl.question('¿Cuál es tu comida favorita? ', { signal }, (answer) => {
  console.log(`Ah, entonces tu comida favorita es ${answer}`);
});

signal.addEventListener('abort', () => {
  console.log('La pregunta sobre la comida se agotó');
}, { once: true });

setTimeout(() => ac.abort(), 10000);

readline.clearLine(stream, dir[, callback])

[Historia]

VersiónCambios
v18.0.0Pasar una callback inválida al argumento callback ahora arroja ERR_INVALID_ARG_TYPE en lugar de ERR_INVALID_CALLBACK.
v12.7.0La callback de write() del stream y el valor de retorno están expuestos.
v0.7.7Añadido en: v0.7.7
  • stream <stream.Writable>

  • dir <number>

    • -1: a la izquierda desde el cursor
    • 1: a la derecha desde el cursor
    • 0: la línea completa
  • callback <Function> Invocada una vez que la operación se completa.

  • Devuelve: <boolean> false si stream desea que el código de llamada espere a que el evento 'drain' sea emitido antes de continuar escribiendo datos adicionales; de lo contrario, true.

El método readline.clearLine() limpia la línea actual del stream TTY dado en una dirección especificada identificada por dir.

readline.clearScreenDown(stream[, callback])

[Historia]

VersiónCambios
v18.0.0Pasar una callback inválida al argumento callback ahora arroja ERR_INVALID_ARG_TYPE en lugar de ERR_INVALID_CALLBACK.
v12.7.0La callback de write() del stream y el valor de retorno están expuestos.
v0.7.7Añadido en: v0.7.7
  • stream <stream.Writable>
  • callback <Function> Invocada una vez que la operación se completa.
  • Devuelve: <boolean> false si stream desea que el código de llamada espere a que el evento 'drain' sea emitido antes de continuar escribiendo datos adicionales; de lo contrario, true.

El método readline.clearScreenDown() limpia el stream TTY dado desde la posición actual del cursor hacia abajo.

readline.createInterface(options)

[Historial]

VersiónCambios
v15.14.0, v14.18.0La opción signal ahora es compatible.
v15.8.0, v14.18.0La opción history ahora es compatible.
v13.9.0La opción tabSize ahora es compatible.
v8.3.0, v6.11.4Eliminar el límite máximo de la opción crlfDelay.
v6.6.0La opción crlfDelay ahora es compatible.
v6.3.0La opción prompt ahora es compatible.
v6.0.0La opción historySize ahora puede ser 0.
v0.1.98Añadido en: v0.1.98
  • options <Objeto>

    • input <stream.Readable> El flujo Readable para escuchar. Esta opción es obligatoria.
    • output <stream.Writable> El flujo Writable para escribir datos de readline.
    • completer <Función> Una función opcional utilizada para la autocompletación con la tecla Tab.
    • terminal <boolean> true si los flujos input y output deben tratarse como un TTY y tener códigos de escape ANSI/VT100 escritos en él. Predeterminado: comprobar isTTY en el flujo output al instanciar.
    • history <string[]> Lista inicial de líneas del historial. Esta opción tiene sentido solo si terminal se establece en true por el usuario o por una comprobación interna de output; de lo contrario, el mecanismo de almacenamiento en caché del historial no se inicializa en absoluto. Predeterminado: [].
    • historySize <number> Número máximo de líneas del historial retenidas. Para deshabilitar el historial, establezca este valor en 0. Esta opción tiene sentido solo si terminal se establece en true por el usuario o por una comprobación interna de output; de lo contrario, el mecanismo de almacenamiento en caché del historial no se inicializa en absoluto. Predeterminado: 30.
    • removeHistoryDuplicates <boolean> Si es true, cuando una nueva línea de entrada añadida a la lista del historial duplica una anterior, esto elimina la línea anterior de la lista. Predeterminado: false.
    • prompt <string> La cadena de solicitud (prompt) que se utilizará. Predeterminado: '\> '.
    • crlfDelay <number> Si el retraso entre \r y \n supera los crlfDelay milisegundos, tanto \r como \n se tratarán como entradas de fin de línea separadas. crlfDelay se convertirá en un número no inferior a 100. Se puede establecer en Infinity, en cuyo caso \r seguido de \n siempre se considerará una única nueva línea (lo cual puede ser razonable para leer archivos con el delimitador de línea \r\n). Predeterminado: 100.
    • escapeCodeTimeout <number> La duración que readline esperará un carácter (al leer una secuencia de teclas ambigua en milisegundos, una que puede formar una secuencia de teclas completa utilizando la entrada leída hasta ahora y puede tomar entrada adicional para completar una secuencia de teclas más larga). Predeterminado: 500.
    • tabSize <integer> El número de espacios al que equivale una tabulación (mínimo 1). Predeterminado: 8.
    • signal <AbortSignal> Permite cerrar la interfaz utilizando un AbortSignal. La anulación de la señal llamará internamente a close en la interfaz.
  • Devuelve: <readline.Interface>

El método readline.createInterface() crea una nueva instancia de readline.Interface.

js
import { createInterface } from 'node:readline';
import { stdin, stdout } from 'node:process';
const rl = createInterface({
  input: stdin,
  output: stdout,
});
js
const { createInterface } = require('node:readline');
const rl = createInterface({
  input: process.stdin,
  output: process.stdout,
});

Una vez creada la instancia de readline.Interface, el caso más común es escuchar el evento 'line':

js
rl.on('line', (line) => {
  console.log(`Recibido: ${line}`);
});

Si terminal es true para esta instancia, entonces el flujo output obtendrá la mejor compatibilidad si define una propiedad output.columns y emite un evento 'resize' en el output si las columnas cambian alguna vez (process.stdout hace esto automáticamente cuando es un TTY).

Al crear una readline.Interface utilizando stdin como entrada, el programa no finalizará hasta que reciba un carácter EOF. Para salir sin esperar la entrada del usuario, llame a process.stdin.unref().

Uso de la función completer

La función completer toma la línea actual introducida por el usuario como argumento y devuelve un Array con 2 entradas:

  • Un Array con las entradas coincidentes para la autocompletación.
  • La subcadena que se utilizó para la coincidencia.

Por ejemplo: [[substr1, substr2, ...], originalsubstring].

js
function completer(line) {
  const completions = '.help .error .exit .quit .q'.split(' ');
  const hits = completions.filter((c) => c.startsWith(line));
  // Mostrar todas las autocompletaciones si no se encuentra ninguna
  return [hits.length ? hits : completions, line];
}

La función completer se puede llamar de forma asíncrona si acepta dos argumentos:

js
function completer(linePartial, callback) {
  callback(null, [['123'], linePartial]);
}

readline.cursorTo(stream, x[, y][, callback])

[Historial]

VersiónCambios
v18.0.0Pasar una devolución de llamada no válida al argumento callback ahora lanza ERR_INVALID_ARG_TYPE en lugar de ERR_INVALID_CALLBACK.
v12.7.0Se exponen la devolución de llamada write() y el valor de retorno del stream.
v0.7.7Agregado en: v0.7.7
  • stream <stream.Writable>
  • x <number>
  • y <number>
  • callback <Function> Se invoca una vez que se completa la operación.
  • Devuelve: <boolean> false si stream desea que el código de llamada espere a que se emita el evento 'drain' antes de continuar escribiendo datos adicionales; de lo contrario, true.

El método readline.cursorTo() mueve el cursor a la posición especificada en un stream TTY dado.

readline.moveCursor(stream, dx, dy[, callback])

[Historial]

VersiónCambios
v18.0.0Pasar una devolución de llamada no válida al argumento callback ahora lanza ERR_INVALID_ARG_TYPE en lugar de ERR_INVALID_CALLBACK.
v12.7.0Se exponen la devolución de llamada write() y el valor de retorno del stream.
v0.7.7Agregado en: v0.7.7
  • stream <stream.Writable>
  • dx <number>
  • dy <number>
  • callback <Function> Se invoca una vez que se completa la operación.
  • Devuelve: <boolean> false si stream desea que el código de llamada espere a que se emita el evento 'drain' antes de continuar escribiendo datos adicionales; de lo contrario, true.

El método readline.moveCursor() mueve el cursor relativamente a su posición actual en un stream TTY dado.

readline.emitKeypressEvents(stream[, interface])

Agregado en: v0.7.7

El método readline.emitKeypressEvents() hace que el flujo Readable dado comience a emitir eventos 'keypress' correspondientes a la entrada recibida.

Opcionalmente, interface especifica una instancia de readline.Interface para la cual se deshabilita la autocompletación cuando se detecta una entrada copiada y pegada.

Si el stream es un TTY, entonces debe estar en modo raw.

Esto es llamado automáticamente por cualquier instancia de readline en su input si el input es una terminal. Cerrar la instancia de readline no detiene la emisión de eventos 'keypress' por parte del input.

js
readline.emitKeypressEvents(process.stdin);
if (process.stdin.isTTY)
  process.stdin.setRawMode(true);

Ejemplo: CLI Pequeña

El siguiente ejemplo ilustra el uso de la clase readline.Interface para implementar una pequeña interfaz de línea de comandos:

js
import { createInterface } from 'node:readline';
import { exit, stdin, stdout } from 'node:process';
const rl = createInterface({
  input: stdin,
  output: stdout,
  prompt: 'OHAI> ',
});

rl.prompt();

rl.on('line', (line) => {
  switch (line.trim()) {
    case 'hello':
      console.log('world!');
      break;
    default:
      console.log(`Say what? I might have heard '${line.trim()}'`);
      break;
  }
  rl.prompt();
}).on('close', () => {
  console.log('Have a great day!');
  exit(0);
});
js
const { createInterface } = require('node:readline');
const rl = createInterface({
  input: process.stdin,
  output: process.stdout,
  prompt: 'OHAI> ',
});

rl.prompt();

rl.on('line', (line) => {
  switch (line.trim()) {
    case 'hello':
      console.log('world!');
      break;
    default:
      console.log(`Say what? I might have heard '${line.trim()}'`);
      break;
  }
  rl.prompt();
}).on('close', () => {
  console.log('Have a great day!');
  process.exit(0);
});

Ejemplo: Leer un flujo de archivos línea por línea

Un caso de uso común para readline es consumir un archivo de entrada una línea a la vez. La forma más fácil de hacerlo es aprovechando la API fs.ReadStream así como un bucle for await...of:

js
import { createReadStream } from 'node:fs';
import { createInterface } from 'node:readline';

async function processLineByLine() {
  const fileStream = createReadStream('input.txt');

  const rl = createInterface({
    input: fileStream,
    crlfDelay: Infinity,
  });
  // Note: we use the crlfDelay option to recognize all instances of CR LF
  // ('\r\n') in input.txt as a single line break.

  for await (const line of rl) {
    // Each line in input.txt will be successively available here as `line`.
    console.log(`Line from file: ${line}`);
  }
}

processLineByLine();
js
const { createReadStream } = require('node:fs');
const { createInterface } = require('node:readline');

async function processLineByLine() {
  const fileStream = createReadStream('input.txt');

  const rl = createInterface({
    input: fileStream,
    crlfDelay: Infinity,
  });
  // Note: we use the crlfDelay option to recognize all instances of CR LF
  // ('\r\n') in input.txt as a single line break.

  for await (const line of rl) {
    // Each line in input.txt will be successively available here as `line`.
    console.log(`Line from file: ${line}`);
  }
}

processLineByLine();

Alternativamente, uno podría usar el evento 'line':

js
import { createReadStream } from 'node:fs';
import { createInterface } from 'node:readline';

const rl = createInterface({
  input: createReadStream('sample.txt'),
  crlfDelay: Infinity,
});

rl.on('line', (line) => {
  console.log(`Line from file: ${line}`);
});
js
const { createReadStream } = require('node:fs');
const { createInterface } = require('node:readline');

const rl = createInterface({
  input: createReadStream('sample.txt'),
  crlfDelay: Infinity,
});

rl.on('line', (line) => {
  console.log(`Line from file: ${line}`);
});

Actualmente, el bucle for await...of puede ser un poco más lento. Si el flujo async / await y la velocidad son esenciales, se puede aplicar un enfoque mixto:

js
import { once } from 'node:events';
import { createReadStream } from 'node:fs';
import { createInterface } from 'node:readline';

(async function processLineByLine() {
  try {
    const rl = createInterface({
      input: createReadStream('big-file.txt'),
      crlfDelay: Infinity,
    });

    rl.on('line', (line) => {
      // Process the line.
    });

    await once(rl, 'close');

    console.log('File processed.');
  } catch (err) {
    console.error(err);
  }
})();
js
const { once } = require('node:events');
const { createReadStream } = require('node:fs');
const { createInterface } = require('node:readline');

(async function processLineByLine() {
  try {
    const rl = createInterface({
      input: createReadStream('big-file.txt'),
      crlfDelay: Infinity,
    });

    rl.on('line', (line) => {
      // Process the line.
    });

    await once(rl, 'close');

    console.log('File processed.');
  } catch (err) {
    console.error(err);
  }
})();

Atajos de teclado TTY

Atajos de tecladoDescripciónNotas
+ +Borrar línea a la izquierdaNo funciona en Linux, Mac ni Windows
+ +Borrar línea a la derechaNo funciona en Mac
+Emitir SIGINT o cerrar la instancia de readline
+Borrar a la izquierda
+Borrar a la derecha o cerrar la instancia de readline en caso de que la línea actual esté vacía / EOFNo funciona en Windows
+Borrar desde la posición actual hasta el inicio de la línea
+Borrar desde la posición actual hasta el final de la línea
+Pegar (Recordar) el texto borrado previamenteSolo funciona con texto borrado por + o +
+Ciclar entre textos borrados previamenteSolo disponible cuando la última pulsación es + o +
+Ir al inicio de la línea
+Ir al final de la línea
+Retroceder un carácter
+Avanzar un carácter
+Limpiar la pantalla
+Siguiente elemento del historial
+Elemento anterior del historial
+Deshacer el cambio anteriorCualquier pulsación de tecla que emita el código de tecla 0x1F realizará esta acción. En muchos terminales, por ejemplo xterm , esto está vinculado a + .
+Rehacer el cambio anteriorMuchos terminales no tienen una pulsación de tecla predeterminada para rehacer. Elegimos el código de tecla 0x1E para realizar la acción de rehacer. En xterm , está vinculado a + de forma predeterminada.
+Mueve el proceso en ejecución al segundo plano. Escriba fg y presione para regresar.No funciona en Windows
+ o +Borrar hacia atrás hasta un límite de palabra+ No funciona en Linux, Mac ni Windows
+Borrar hacia adelante hasta un límite de palabraNo funciona en Mac
+ o +Palabra a la izquierda+ No funciona en Mac
+ o +Palabra a la derecha+ No funciona en Mac
+ o +Borrar palabra a la derecha+ No funciona en Windows
+Borrar palabra a la izquierdaNo funciona en Mac