Menu

readline in Node.js: leggere l'input utente dal terminale

Node.js non ha una funzione prompt(). Per fare una domanda all'utente nel terminale, crea un'interfaccia readline su process.stdin e chiama question(), oppure fai await con readline/promises.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Per leggere l'input dell'utente in Node.js, crea un'interfaccia readline su process.stdin e fai la domanda con rl.question(). Node.js non ha prompt(): la versione del browser apre una finestra di dialogo, e un programma da terminale non ne ha. La forma moderna usa readline/promises, dove await rl.question('Name? ') restituisce la riga scritta dall'utente. Chiudi l'interfaccia quando hai finito, altrimenti il programma resta in attesa di altro input.

question() ha stampato il suo prompt, ha aspettato una riga di input e l'ha restituita senza l'a capo, quindi il programma ha stampato Next year you will be 37. Per più domande, fai await di una question() dopo l'altra.

question() di readline con una callback

L'API originale, presente in ogni versione di Node.js, passa la risposta a una callback. Domande annidate vogliono callback annidate:

Ha stampato il prompt, poi You picked blue. La risposta è una semplice stringa, quindi falle trim prima di confrontarla: altrimenti un utente che scrive uno spazio dopo la parola ottiene 'blue ', che non è uguale a 'blue'.

Leggere l'input riga per riga

Per elaborare ogni riga finché l'input non finisce, scorri l'interfaccia con for await. È così che un programma legge una lista scritta dall'utente (chiusa con Ctrl+D) o un file passato con node index.js < numbers.txt. Il codice più vecchio fa lo stesso con gli eventi, rl.on('line', fn) per ogni riga e rl.on('close', fn) alla fine; il ciclo è quella coppia di eventi scritta dall'alto verso il basso:

Ha stampato 3 numbers, total 49, e il ciclo è finito da solo quando è finito l'input, quindi non serve close(). Aggiungi una quarta riga di input, 1, e il risultato diventa 4 numbers, total 50.

Leggere tutto lo stdin in una volta

Per un input che arriva in pipe da un altro programma (cat data.txt | node index.js), leggere tutto con una sola chiamata è più semplice. Il file descriptor 0 è lo standard input. Un file salvato su Windows può chiudere le righe con \r\n, quindi dividi su /\r?\n/ quando l'input può arrivare da lì:

Ha stampato i tre articoli in colonna. readFileSync(0) blocca finché l'input non è completo, il che va bene per uno script che legge da una pipe e per i test, ma non per uno strumento interattivo, dove l'utente scriverebbe tutto prima di vedere un qualsiasi prompt.

Quale usare

Tutti e quattro leggono lo stesso standard input. Cambia quando il tuo codice riceve il testo: una risposta alla volta, una riga alla volta o tutto alla fine.

Ti serveUsa
Fare alcune domande in ordinereadline/promises con await rl.question()
Supportare versioni di Node.js precedenti alla 17readline con una callback di question()
Gestire ogni riga appena arrivafor await (const line of rl)
Leggere un'intera pipe o un file da stdinfs.readFileSync(0, 'utf8')
Valori noti prima dell'avvio del programmaInvece process.argv

Errori comuni

Dimenticare rl.close(). L'interfaccia tiene aperto lo standard input, quindi il programma non termina mai dopo l'ultima domanda. Chiudila quando hai tutte le risposte.

Usare la risposta come numero. Come tutto quello che si scrive in un terminale, la risposta è una stringa. '36' + 1 è '361'; converti prima con Number().

Passare in pipe più risposte a più domande. Quando l'input arriva da una pipe invece che dalla tastiera, readline lo legge tutto in una volta, e una riga che arriva prima che venga fatta la sua question() va persa. Per l'input in pipe usa il ciclo for await o readFileSync(0).

Omettere l'opzione output. Senza output: process.stdout, question() non stampa mai il suo prompt, e l'utente fissa un terminale vuoto. Il ciclo riga per riga non ne ha bisogno, perché non stampa niente.

Domande frequenti

Perché prompt non è definito in Node.js?

prompt() è una funzione del browser che apre una finestra di dialogo, e Node.js non ha una finestra in cui aprirla. In Node.js usa readline, oppure un pacchetto come prompts o inquirer per menu e campi password.

Come leggo una password senza mostrarla?

readline mostra ogni tasto. Pacchetti come prompts o @inquirer/password nascondono l'input; farlo da solo significa mettere il terminale in modalità raw con process.stdin.setRawMode(true) e gestire ogni tasto.

Meglio readline o process.argv?

Usa process.argv quando i valori sono noti prima che il programma parta, così può girare in uno script senza nessuno davanti. Usa readline per gli strumenti interattivi che fanno una domanda dopo l'altra.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

Inizia