Skip to content

Readline

[Stabile: 2 - Stabile]

Stabile: 2 Stabilità: 2 - Stabile

Codice Sorgente: lib/readline.js

Il modulo node:readline fornisce un'interfaccia per la lettura dei dati da uno stream Readable (come process.stdin) riga per riga.

Per utilizzare le API basate su promise:

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

Per utilizzare le API con callback e sincrona:

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

Il seguente semplice esempio illustra l'uso di base del modulo 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('Cosa ne pensi di Node.js? ')

console.log(`Grazie per il tuo prezioso feedback: ${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('Cosa ne pensi di Node.js? ', answer => {
  // TODO: Registra la risposta in un database
  console.log(`Grazie per il tuo prezioso feedback: ${answer}`)

  rl.close()
})

Una volta invocato questo codice, l'applicazione Node.js non terminerà finché l'interfaccia readline.Interface non sarà chiusa, perché l'interfaccia attende la ricezione dei dati dallo stream input.

Classe: InterfaceConstructor

Aggiunto in: v0.1.104

Le istanze della classe InterfaceConstructor sono costruite usando il metodo readlinePromises.createInterface() o readline.createInterface(). Ogni istanza è associata a un singolo stream input Readable e a un singolo stream output Writable. Lo stream output viene utilizzato per stampare i prompt per l'input utente che arriva e viene letto dallo stream input.

Evento: 'close'

Aggiunto in: v0.1.98

L'evento 'close' viene emesso quando si verifica uno dei seguenti eventi:

  • Viene chiamato il metodo rl.close() e l'istanza InterfaceConstructor ha rilasciato il controllo sui flussi input e output;
  • Il flusso input riceve il suo evento 'end';
  • Il flusso input riceve + per segnalare la fine della trasmissione (EOT);
  • Il flusso input riceve + per segnalare SIGINT e non è registrato alcun listener per l'evento 'SIGINT' sull'istanza InterfaceConstructor.

La funzione listener viene chiamata senza passare alcun argomento.

L'istanza InterfaceConstructor termina una volta emesso l'evento 'close'.

Evento: 'line'

Aggiunto in: v0.1.98

L'evento 'line' viene emesso ogni volta che il flusso input riceve un input di fine riga (\n, \r, o \r\n). Questo di solito si verifica quando l'utente preme o .

L'evento 'line' viene emesso anche se sono stati letti nuovi dati da un flusso e quel flusso termina senza un marcatore di fine riga finale.

La funzione listener viene chiamata con una stringa contenente l'unica riga di input ricevuta.

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

Evento: 'history'

Aggiunto in: v15.8.0, v14.18.0

L'evento 'history' viene emesso ogni volta che la matrice history è cambiata.

La funzione listener viene chiamata con una matrice contenente la matrice history. Rifletterà tutte le modifiche, le righe aggiunte e le righe rimosse a causa di historySize e removeHistoryDuplicates.

Lo scopo principale è quello di permettere a un listener di persistere la cronologia. È anche possibile per il listener modificare l'oggetto history. Questo potrebbe essere utile per impedire che determinate righe vengano aggiunte alla cronologia, come una password.

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

Evento: 'pause'

Aggiunto in: v0.7.5

L'evento 'pause' viene emesso quando si verifica uno dei seguenti eventi:

  • Il flusso input è in pausa.
  • Il flusso input non è in pausa e riceve l'evento 'SIGCONT'. (Vedi eventi 'SIGTSTP' e 'SIGCONT'.)

La funzione listener viene chiamata senza passare alcun argomento.

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

Evento: 'resume'

Aggiunto in: v0.7.5

L'evento 'resume' viene emesso ogni volta che lo stream input viene ripreso.

La funzione listener viene chiamata senza passare alcun argomento.

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

Evento: 'SIGCONT'

Aggiunto in: v0.7.5

L'evento 'SIGCONT' viene emesso quando un processo Node.js precedentemente spostato in background usando + (cioè SIGTSTP) viene poi riportato in primo piano usando fg(1p).

Se lo stream input è stato messo in pausa prima della richiesta SIGTSTP, questo evento non verrà emesso.

La funzione listener viene invocata senza passare alcun argomento.

js
rl.on('SIGCONT', () => {
  // `prompt` riprenderà automaticamente lo stream
  rl.prompt()
})

L'evento 'SIGCONT' non è supportato su Windows.

Evento: 'SIGINT'

Aggiunto in: v0.3.0

L'evento 'SIGINT' viene emesso ogni volta che lo stream input riceve un input, tipicamente noto come SIGINT. Se non sono registrati listener per l'evento 'SIGINT' quando lo stream input riceve un SIGINT, verrà emesso l'evento 'pause'.

La funzione listener viene invocata senza passare alcun argomento.

js
rl.on('SIGINT', () => {
  rl.question('Sei sicuro di voler uscire? ', answer => {
    if (answer.match(/^y(es)?$/i)) rl.pause()
  })
})

Evento: 'SIGTSTP'

Aggiunto in: v0.7.5

L'evento 'SIGTSTP' viene emesso quando lo stream input riceve un input +, tipicamente noto come SIGTSTP. Se non sono registrati listener per l'evento 'SIGTSTP' quando lo stream input riceve un SIGTSTP, il processo Node.js verrà inviato in background.

Quando il programma viene ripreso usando fg(1p), verranno emessi gli eventi 'pause' e 'SIGCONT'. Questi possono essere utilizzati per riprendere lo stream input.

Gli eventi 'pause' e 'SIGCONT' non verranno emessi se l'input è stato messo in pausa prima che il processo venisse inviato in background.

La funzione listener viene invocata senza passare alcun argomento.

js
rl.on('SIGTSTP', () => {
  // Questo sovrascriverà SIGTSTP e impedirà al programma di andare in
  // background.
  console.log('SIGTSTP intercettato.')
})

L'evento 'SIGTSTP' non è supportato su Windows.

rl.close()

Aggiunto in: v0.1.98

Il metodo rl.close() chiude l'istanza InterfaceConstructor e rilascia il controllo sui flussi input e output. Quando viene chiamato, viene emesso l'evento 'close'.

Chiamare rl.close() non interrompe immediatamente l'emissione di altri eventi (incluso 'line') dall'istanza InterfaceConstructor.

rl.pause()

Aggiunto in: v0.3.4

Il metodo rl.pause() mette in pausa il flusso input, permettendo di riprenderlo in seguito se necessario.

Chiamare rl.pause() non interrompe immediatamente l'emissione di altri eventi (incluso 'line') dall'istanza InterfaceConstructor.

rl.prompt([preserveCursor])

Aggiunto in: v0.1.98

  • preserveCursor <boolean> Se true, impedisce che il posizionamento del cursore venga ripristinato a 0.

Il metodo rl.prompt() scrive il prompt configurato dell'istanza InterfaceConstructor su una nuova riga in output per fornire all'utente una nuova posizione in cui fornire input.

Quando viene chiamato, rl.prompt() riprende il flusso input se è stato messo in pausa.

Se InterfaceConstructor è stato creato con output impostato su null o undefined, il prompt non viene scritto.

rl.resume()

Aggiunto in: v0.3.4

Il metodo rl.resume() riprende il flusso input se è stato messo in pausa.

rl.setPrompt(prompt)

Aggiunto in: v0.1.98

Il metodo rl.setPrompt() imposta il prompt che verrà scritto su output ogni volta che viene chiamato rl.prompt().

rl.getPrompt()

Aggiunto in: v15.3.0, v14.17.0

  • Restituisce: <string> la stringa del prompt corrente

Il metodo rl.getPrompt() restituisce il prompt corrente utilizzato da rl.prompt().

rl.write(data[, key])

Aggiunto in: v0.1.98

Il metodo rl.write() scriverà data o una sequenza di tasti identificata da key sull'output. L'argomento key è supportato solo se output è un terminale di testo TTY. Vedi combinazioni di tasti TTY per un elenco di combinazioni di tasti.

Se key è specificato, data viene ignorato.

Quando viene chiamato, rl.write() riprende il flusso input se è stato messo in pausa.

Se InterfaceConstructor è stato creato con output impostato su null o undefined, data e key non vengono scritti.

js
rl.write('Elimina questo!')
// Simula Ctrl+U per eliminare la riga scritta precedentemente
rl.write(null, { ctrl: true, name: 'u' })

Il metodo rl.write() scriverà i dati nell'input dell'Interface readline come se fossero forniti dall'utente.

rl[Symbol.asyncIterator]()

[Cronologia]

VersioneModifiche
v11.14.0, v10.17.0Il supporto di Symbol.asyncIterator non è più sperimentale.
v11.4.0, v10.16.0Aggiunto in: v11.4.0, v10.16.0

Crea un oggetto AsyncIterator che itera su ogni riga nel flusso di input come stringa. Questo metodo consente l'iterazione asincrona di oggetti InterfaceConstructor tramite cicli for await...of.

Gli errori nel flusso di input non vengono inoltrati.

Se il ciclo viene terminato con break, throw o return, verrà chiamato rl.close(). In altre parole, l'iterazione su un InterfaceConstructor consumerà sempre completamente il flusso di input.

Le prestazioni non sono paragonabili all'API tradizionale dell'evento 'line'. Utilizzare 'line' per applicazioni sensibili alle prestazioni.

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

  for await (const line of rl) {
    // Ogni riga nell'input readline sarà successivamente disponibile qui come
    // `line`.
  }
}

readline.createInterface() inizia a consumare il flusso di input una volta invocato. Avere operazioni asincrone tra la creazione dell'interfaccia e l'iterazione asincrona può comportare la perdita di righe.

rl.line

[Cronologia]

VersioneModifiche
v15.8.0, v14.18.0Il valore sarà sempre una stringa, mai indefinito.
v0.1.98Aggiunto in: v0.1.98

I dati di input correnti in elaborazione da parte di Node.

Questo può essere utilizzato quando si raccolgono input da un flusso TTY per recuperare il valore corrente che è stato elaborato finora, prima che venga emesso l'evento line. Una volta emesso l'evento line, questa proprietà sarà una stringa vuota.

Essere consapevoli che la modifica del valore durante l'esecuzione dell'istanza può avere conseguenze impreviste se rl.cursor non viene anche controllato.

Se non si utilizza un flusso TTY per l'input, utilizzare l'evento 'line'.

Un possibile caso d'uso sarebbe il seguente:

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

Aggiunto in: v0.1.98

La posizione del cursore relativa a rl.line.

Questo tiene traccia di dove si posiziona il cursore corrente nella stringa di input, durante la lettura dell'input da un flusso TTY. La posizione del cursore determina la parte della stringa di input che verrà modificata durante l'elaborazione dell'input, nonché la colonna in cui verrà visualizzato il caret del terminale.

rl.getCursorPos()

Aggiunto in: v13.5.0, v12.16.0

  • Restituisce: <Object>
    • rows <number> la riga del prompt su cui si trova attualmente il cursore
    • cols <number> la colonna dello schermo su cui si trova attualmente il cursore

Restituisce la posizione reale del cursore in relazione al prompt di input + stringa. Stringhe di input lunghe (a capo), così come i prompt a più righe sono inclusi nei calcoli.

Promises API

Aggiunto in: v17.0.0

[Stabile: 1 - Sperimentale]

Stabile: 1 Stabilità: 1 - Sperimentale

Classe: readlinePromises.Interface

Aggiunto in: v17.0.0

Le istanze della classe readlinePromises.Interface sono costruite usando il metodo readlinePromises.createInterface(). Ogni istanza è associata a un singolo flusso input Readable e a un singolo flusso output Writable. Il flusso output viene utilizzato per stampare i prompt per l'input dell'utente che arriva e viene letto dal flusso input.

rl.question(query[, options])

Aggiunto in: v17.0.0

  • query <string> Un'istruzione o una query da scrivere su output, anteposta al prompt.

  • options <Object>

    • signal <AbortSignal> Consente facoltativamente di annullare question() usando un AbortSignal.
  • Restituisce: <Promise> Una promessa che viene soddisfatta con l'input dell'utente in risposta alla query.

Il metodo rl.question() visualizza la query scrivendola su output, attende che l'input dell'utente venga fornito su input, quindi invoca la funzione callback passando l'input fornito come primo argomento.

Quando viene chiamato, rl.question() riprenderà il flusso input se è stato messo in pausa.

Se readlinePromises.Interface è stato creato con output impostato su null o undefined, la query non viene scritta.

Se la domanda viene effettuata dopo rl.close(), viene restituita una promessa rifiutata.

Esempio di utilizzo:

js
const answer = await rl.question('Qual è il tuo cibo preferito? ')
console.log(`Oh, quindi il tuo cibo preferito è ${answer}`)

Utilizzo di AbortSignal per annullare una domanda.

js
const signal = AbortSignal.timeout(10_000)

signal.addEventListener(
  'abort',
  () => {
    console.log('La domanda sul cibo è scaduta')
  },
  { once: true }
)

const answer = await rl.question('Qual è il tuo cibo preferito? ', { signal })
console.log(`Oh, quindi il tuo cibo preferito è ${answer}`)

Classe: readlinePromises.Readline

Aggiunto in: v17.0.0

new readlinePromises.Readline(stream[, options])

Aggiunto in: v17.0.0

rl.clearLine(dir)

Aggiunto in: v17.0.0

  • dir <intero>

    • -1: a sinistra del cursore
    • 1: a destra del cursore
    • 0: l'intera riga
  • Restituisce: this

Il metodo rl.clearLine() aggiunge all'elenco interno delle azioni in sospeso un'azione che cancella la riga corrente dello stream associato in una direzione specifica identificata da dir. Chiamare rl.commit() per vedere l'effetto di questo metodo, a meno che autoCommit: true non sia stato passato al costruttore.

rl.clearScreenDown()

Aggiunto in: v17.0.0

  • Restituisce: this

Il metodo rl.clearScreenDown() aggiunge all'elenco interno delle azioni in sospeso un'azione che cancella lo stream associato dalla posizione corrente del cursore in giù. Chiamare rl.commit() per vedere l'effetto di questo metodo, a meno che autoCommit: true non sia stato passato al costruttore.

rl.commit()

Aggiunto in: v17.0.0

Il metodo rl.commit() invia tutte le azioni in sospeso allo stream associato e cancella l'elenco interno delle azioni in sospeso.

rl.cursorTo(x[, y])

Aggiunto in: v17.0.0

Il metodo rl.cursorTo() aggiunge all'elenco interno delle azioni in sospeso un'azione che sposta il cursore nella posizione specificata nello stream associato. Chiamare rl.commit() per vedere l'effetto di questo metodo, a meno che autoCommit: true non sia stato passato al costruttore.

rl.moveCursor(dx, dy)

Aggiunto in: v17.0.0

Il metodo rl.moveCursor() aggiunge all'elenco interno delle azioni in sospeso un'azione che sposta il cursore relativamente alla sua posizione corrente nello stream associato. Chiamare rl.commit() per vedere l'effetto di questo metodo, a meno che autoCommit: true non sia stato passato al costruttore.

rl.rollback()

Aggiunto in: v17.0.0

  • Restituisce: this

Il metodo rl.rollback cancella l'elenco interno delle azioni in sospeso senza inviarlo allo stream associato.

readlinePromises.createInterface(options)

Aggiunto in: v17.0.0

  • options <Object>

    • input <stream.Readable> Lo stream Readable da ascoltare. Questa opzione è obbligatoria.
    • output <stream.Writable> Lo stream Writable su cui scrivere i dati readline.
    • completer <Function> Una funzione opzionale utilizzata per il completamento automatico con Tab.
    • terminal <boolean> true se gli stream input e output devono essere trattati come un TTY e devono avere codici di escape ANSI/VT100 scritti su di essi. Default: verifica isTTY sullo stream output al momento dell'istanza.
    • history <string[]> Elenco iniziale di righe di cronologia. Questa opzione ha senso solo se terminal è impostato su true dall'utente o da un controllo output interno, altrimenti il meccanismo di memorizzazione nella cache della cronologia non viene inizializzato affatto. Default: [].
    • historySize <number> Numero massimo di righe di cronologia mantenute. Per disabilitare la cronologia impostare questo valore su 0. Questa opzione ha senso solo se terminal è impostato su true dall'utente o da un controllo output interno, altrimenti il meccanismo di memorizzazione nella cache della cronologia non viene inizializzato affatto. Default: 30.
    • removeHistoryDuplicates <boolean> Se true, quando una nuova riga di input aggiunta all'elenco cronologia ne duplica una più vecchia, questa rimuove la riga più vecchia dall'elenco. Default: false.
    • prompt <string> La stringa di prompt da utilizzare. Default: '\> '.
    • crlfDelay <number> Se il ritardo tra \r e \n supera crlfDelay millisecondi, sia \r che \n saranno trattati come input di fine riga separati. crlfDelay sarà forzato a un numero non inferiore a 100. Può essere impostato su Infinity, nel qual caso \r seguito da \n sarà sempre considerato una singola nuova riga (il che potrebbe essere ragionevole per leggere file con delimitatore di riga \r\n). Default: 100.
    • escapeCodeTimeout <number> La durata in cui readlinePromises attenderà un carattere (durante la lettura di una sequenza di tasti ambigua in millisecondi, una che può sia formare una sequenza di tasti completa usando l'input letto finora e può richiedere input aggiuntivi per completare una sequenza di tasti più lunga). Default: 500.
    • tabSize <integer> Il numero di spazi a cui equivale un tab (minimo 1). Default: 8.
  • Restituisce: <readlinePromises.Interface>

Il metodo readlinePromises.createInterface() crea una nuova istanza 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 volta creata l'istanza readlinePromises.Interface, il caso più comune è quello di ascoltare l'evento 'line':

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

Se terminal è true per questa istanza, lo stream output otterrà la migliore compatibilità se definisce una proprietà output.columns ed emette un evento 'resize' sull' output se o quando le colonne cambiano (process.stdout lo fa automaticamente quando è un TTY).

Uso della funzione completer

La funzione completer accetta come argomento la riga corrente inserita dall'utente e restituisce un Array con 2 elementi:

  • Un Array con le voci corrispondenti per il completamento.
  • La sottostringa utilizzata per la corrispondenza.

Ad esempio: [[substr1, substr2, ...], originalsubstring].

js
function completer(line) {
  const completions = '.help .error .exit .quit .q'.split(' ')
  const hits = completions.filter(c => c.startsWith(line))
  // Mostra tutti i completamenti se non ne vengono trovati
  return [hits.length ? hits : completions, line]
}

La funzione completer può anche restituire una <Promise>, o essere asincrona:

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

API Callback

Aggiunto in: v0.1.104

Classe: readline.Interface

[Cronologia]

VersioneModifiche
v17.0.0La classe readline.Interface ora eredita da Interface.
v0.1.104Aggiunto in: v0.1.104

Le istanze della classe readline.Interface vengono costruite usando il metodo readline.createInterface(). Ogni istanza è associata a un singolo flusso input Readable e a un singolo flusso output Writable. Il flusso output viene utilizzato per stampare i prompt per l'input dell'utente che arriva e viene letto dal flusso input.

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

Aggiunto in: v0.3.3

  • query <string> Un'affermazione o una query da scrivere su output, anteposta al prompt.

  • options <Object>

    • signal <AbortSignal> Consente facoltativamente di annullare question() usando un AbortController.
  • callback <Function> Una funzione di callback che viene invocata con l'input dell'utente in risposta alla query.

Il metodo rl.question() visualizza la query scrivendola su output, attende che l'input dell'utente venga fornito su input, quindi invoca la funzione callback passando l'input fornito come primo argomento.

Quando viene chiamato, rl.question() riprenderà il flusso input se è stato messo in pausa.

Se readline.Interface è stato creato con output impostato su null o undefined, la query non viene scritta.

La funzione callback passata a rl.question() non segue il modello tipico di accettazione di un oggetto Error o null come primo argomento. La callback viene chiamata con la risposta fornita come unico argomento.

Verra generato un errore se si chiama rl.question() dopo rl.close().

Esempio di utilizzo:

js
rl.question('Qual è il tuo cibo preferito? ', answer => {
  console.log(`Oh, quindi il tuo cibo preferito è ${answer}`)
})

Utilizzo di un AbortController per annullare una domanda.

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

rl.question('Qual è il tuo cibo preferito? ', { signal }, answer => {
  console.log(`Oh, quindi il tuo cibo preferito è ${answer}`)
})

signal.addEventListener(
  'abort',
  () => {
    console.log('La domanda sul cibo è scaduta')
  },
  { once: true }
)

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

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

[Cronologia]

VersioneModifiche
v18.0.0Passare un callback non valido all'argomento callback ora genera ERR_INVALID_ARG_TYPE invece di ERR_INVALID_CALLBACK.
v12.7.0Il callback e il valore di ritorno di stream.write() sono esposti.
v0.7.7Aggiunto in: v0.7.7
  • stream <stream.Writable>

  • dir <number>

    • -1: a sinistra del cursore
    • 1: a destra del cursore
    • 0: l'intera riga
  • callback <Function> Viene invocato una volta completata l'operazione.

  • Restituisce: <boolean> false se stream desidera che il codice chiamante attenda l'emissione dell'evento 'drain' prima di continuare a scrivere dati aggiuntivi; altrimenti true.

Il metodo readline.clearLine() cancella la riga corrente del flusso TTY specificato in una direzione specificata da dir.

readline.clearScreenDown(stream[, callback])

[Cronologia]

VersioneModifiche
v18.0.0Passare un callback non valido all'argomento callback ora genera ERR_INVALID_ARG_TYPE invece di ERR_INVALID_CALLBACK.
v12.7.0Il callback e il valore di ritorno di stream.write() sono esposti.
v0.7.7Aggiunto in: v0.7.7
  • stream <stream.Writable>
  • callback <Function> Viene invocato una volta completata l'operazione.
  • Restituisce: <boolean> false se stream desidera che il codice chiamante attenda l'emissione dell'evento 'drain' prima di continuare a scrivere dati aggiuntivi; altrimenti true.

Il metodo readline.clearScreenDown() cancella il flusso TTY specificato dalla posizione corrente del cursore in giù.

readline.createInterface(options)

[Cronologia]

VersioneModifiche
v15.14.0, v14.18.0Ora è supportata l'opzione signal.
v15.8.0, v14.18.0Ora è supportata l'opzione history.
v13.9.0Ora è supportata l'opzione tabSize.
v8.3.0, v6.11.4Rimosso il limite massimo dell'opzione crlfDelay.
v6.6.0Ora è supportata l'opzione crlfDelay.
v6.3.0Ora è supportata l'opzione prompt.
v6.0.0L'opzione historySize può ora essere 0.
v0.1.98Aggiunto in: v0.1.98
  • options <Oggetto>

    • input <stream.Readable> Il flusso Readable da ascoltare. Questa opzione è obbligatoria.
    • output <stream.Writable> Il flusso Writable su cui scrivere i dati readline.
    • completer <Funzione> Una funzione opzionale utilizzata per il completamento automatico tramite Tab.
    • terminal <booleano> true se i flussi input e output devono essere trattati come un TTY e avere codici di escape ANSI/VT100 scritti su di essi. Predefinito: controllo di isTTY sul flusso output al momento dell'istanza.
    • history <string[]> Elenco iniziale delle righe di cronologia. Questa opzione ha senso solo se terminal è impostato su true dall'utente o da un controllo output interno, altrimenti il meccanismo di memorizzazione nella cache della cronologia non viene inizializzato affatto. Predefinito: [].
    • historySize <numero> Numero massimo di righe di cronologia conservate. Per disabilitare la cronologia impostare questo valore su 0. Questa opzione ha senso solo se terminal è impostato su true dall'utente o da un controllo output interno, altrimenti il meccanismo di memorizzazione nella cache della cronologia non viene inizializzato affatto. Predefinito: 30.
    • removeHistoryDuplicates <booleano> Se true, quando una nuova riga di input aggiunta all'elenco della cronologia ne duplica una più vecchia, questa rimuove la riga più vecchia dall'elenco. Predefinito: false.
    • prompt <stringa> La stringa di prompt da utilizzare. Predefinito: '\> '.
    • crlfDelay <numero> Se il ritardo tra \r e \n supera i crlfDelay millisecondi, sia \r che \n saranno trattati come input di fine riga separati. crlfDelay sarà convertito in un numero non inferiore a 100. Può essere impostato su Infinity, nel qual caso \r seguito da \n sarà sempre considerato un singolo carattere di nuova riga (il che potrebbe essere ragionevole per leggere file con delimitatore di riga \r\n). Predefinito: 100.
    • escapeCodeTimeout <numero> La durata in cui readline attenderà un carattere (durante la lettura di una sequenza di tasti ambigua in millisecondi, una che può sia formare una sequenza di tasti completa usando l'input letto finora e può accettare input aggiuntivi per completare una sequenza di tasti più lunga). Predefinito: 500.
    • tabSize <intero> Il numero di spazi a cui equivale un tab (minimo 1). Predefinito: 8.
    • signal <AbortSignal> Consente la chiusura dell'interfaccia usando un AbortSignal. L'interruzione del segnale chiamerà internamente close sull'interfaccia.
  • Restituisce: <readline.Interface>

Il metodo readline.createInterface() crea una nuova istanza 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 volta creata l'istanza readline.Interface, il caso più comune è quello di ascoltare l'evento 'line':

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

Se terminal è true per questa istanza, il flusso output otterrà la migliore compatibilità se definisce una proprietà output.columns ed emette un evento 'resize' sull'output se o quando le colonne cambiano (process.stdout lo fa automaticamente quando è un TTY).

Quando si crea un readline.Interface usando stdin come input, il programma non terminerà finché non riceverà un carattere EOF. Per uscire senza attendere l'input dell'utente, chiamare process.stdin.unref().

Uso della funzione completer

La funzione completer accetta come argomento la riga corrente inserita dall'utente e restituisce un Array con 2 elementi:

  • Un Array con le voci corrispondenti per il completamento.
  • La sottostringa utilizzata per la corrispondenza.

Ad esempio: [[substr1, substr2, ...], originalsubstring].

js
function completer(line) {
  const completions = '.help .error .exit .quit .q'.split(' ')
  const hits = completions.filter(c => c.startsWith(line))
  // Mostra tutti i completamenti se nessuno trovato
  return [hits.length ? hits : completions, line]
}

La funzione completer può essere chiamata in modo asincrono se accetta due argomenti:

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

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

[Cronologia]

VersioneModifiche
v18.0.0Passare un callback non valido all'argomento callback ora genera ERR_INVALID_ARG_TYPE invece di ERR_INVALID_CALLBACK.
v12.7.0Il callback e il valore di ritorno di stream.write() sono esposti.
v0.7.7Aggiunto in: v0.7.7
  • stream <stream.Writable>
  • x <number>
  • y <number>
  • callback <Function> Viene invocato una volta completata l'operazione.
  • Restituisce: <boolean> false se stream desidera che il codice chiamante aspetti che venga emesso l'evento 'drain' prima di continuare a scrivere dati aggiuntivi; altrimenti true.

Il metodo readline.cursorTo() sposta il cursore nella posizione specificata in un dato flusso stream TTY.

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

[Cronologia]

VersioneModifiche
v18.0.0Passare un callback non valido all'argomento callback ora genera ERR_INVALID_ARG_TYPE invece di ERR_INVALID_CALLBACK.
v12.7.0Il callback e il valore di ritorno di stream.write() sono esposti.
v0.7.7Aggiunto in: v0.7.7
  • stream <stream.Writable>
  • dx <number>
  • dy <number>
  • callback <Function> Viene invocato una volta completata l'operazione.
  • Restituisce: <boolean> false se stream desidera che il codice chiamante aspetti che venga emesso l'evento 'drain' prima di continuare a scrivere dati aggiuntivi; altrimenti true.

Il metodo readline.moveCursor() sposta il cursore relativamente alla sua posizione corrente in un dato flusso stream TTY.

readline.emitKeypressEvents(stream[, interface])

Aggiunto in: v0.7.7

Il metodo readline.emitKeypressEvents() fa sì che il flusso Readable dato inizi a emettere eventi 'keypress' corrispondenti all'input ricevuto.

Opzionalmente, interface specifica un'istanza readline.Interface per cui il completamento automatico è disabilitato quando viene rilevato un input copiato e incollato.

Se stream è un TTY, allora deve essere in modalità raw.

Questo viene chiamato automaticamente da qualsiasi istanza readline sul suo input se l'input è un terminale. La chiusura dell'istanza readline non impedisce all'input di emettere eventi 'keypress'.

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

Esempio: Tiny CLI

Il seguente esempio illustra l'utilizzo della classe readline.Interface per implementare una piccola interfaccia a riga di comando:

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)
})

Esempio: Lettura di un flusso di file riga per riga

Un caso d'uso comune per readline è consumare un file di input una riga alla volta. Il modo più semplice per farlo è sfruttare l'API fs.ReadStream e un ciclo 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,
  })
  // Nota: utilizziamo l'opzione crlfDelay per riconoscere tutte le istanze di CR LF
  // ('\r\n') in input.txt come un singolo ritorno a capo.

  for await (const line of rl) {
    // Ogni riga in input.txt sarà successivamente disponibile qui come `line`.
    console.log(`Riga dal 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,
  })
  // Nota: utilizziamo l'opzione crlfDelay per riconoscere tutte le istanze di CR LF
  // ('\r\n') in input.txt come un singolo ritorno a capo.

  for await (const line of rl) {
    // Ogni riga in input.txt sarà successivamente disponibile qui come `line`.
    console.log(`Riga dal file: ${line}`)
  }
}

processLineByLine()

In alternativa, si potrebbe utilizzare l'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(`Riga dal 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(`Riga dal file: ${line}`)
})

Attualmente, il ciclo for await...of può essere un po' più lento. Se il flusso async/await e la velocità sono entrambi essenziali, è possibile applicare un approccio misto:

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 => {
      // Processa la riga.
    })

    await once(rl, 'close')

    console.log('File elaborato.')
  } 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 => {
      // Processa la riga.
    })

    await once(rl, 'close')

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

Tasti di scelta rapida TTY

Tasti di scelta rapidaDescrizioneNote
+ +Elimina riga a sinistraNon funziona su Linux, Mac e Windows
+ +Elimina riga a destraNon funziona su Mac
+Invia SIGINT o chiude l'istanza readline
+Elimina a sinistra
+Elimina a destra o chiude l'istanza readline se la riga corrente è vuota / EOFNon funziona su Windows
+Elimina dalla posizione corrente all'inizio della riga
+Elimina dalla posizione corrente alla fine della riga
+Incolla (Recupera) il testo precedentemente eliminatoFunziona solo con il testo eliminato da + o +
+Passa tra i testi precedentemente eliminatiDisponibile solo quando l'ultimo colpo di tasto è + o +
+Vai all'inizio della riga
+Vai alla fine della riga
+Indietro di un carattere
+Avanti di un carattere
+Pulisci schermo
+Elemento cronologia successivo
+Elemento cronologia precedente
+Annulla la modifica precedenteQualsiasi colpo di tasto che emette il codice chiave 0x1F eseguirà questa azione. In molti terminali, ad esempio xterm , questo è associato a + .
+Ripristina la modifica precedenteMolti terminali non hanno un tasto di scelta rapida di ripristino predefinito. Scegliamo il codice chiave 0x1E per eseguire il ripristino. In xterm , è associato a + per impostazione predefinita.
+Sposta il processo in esecuzione in background. Digitare fg e premere per tornare.Non funziona su Windows
+ o +Elimina all'indietro fino a un limite di parola+ Non funziona su Linux, Mac e Windows
+Elimina in avanti fino a un limite di parolaNon funziona su Mac
+ o +Parola a sinistra+ Non funziona su Mac
+ o +Parola a destra+ Non funziona su Mac
+ o +Elimina parola a destra+ Non funziona su Windows
+Elimina parola a sinistraNon funziona su Mac