Menu

readline no Node.js: ler entrada do usuário no terminal

O Node.js não tem função prompt(). Para fazer uma pergunta ao usuário no terminal, crie uma interface readline em process.stdin e chame question(), ou use await com readline/promises.

Esta página tem editores executáveis. Edite, execute e veja a saída na hora.

Para ler a entrada do usuário no Node.js, crie uma interface readline em process.stdin e pergunte com rl.question(). O Node.js não tem prompt(): a versão do navegador abre uma caixa de diálogo, e um programa de terminal não tem nenhuma. A forma moderna usa readline/promises, em que await rl.question('Name? ') retorna a linha que o usuário digitou. Feche a interface quando terminar, ou o programa continua esperando mais entrada.

question() imprimiu o prompt, esperou uma linha de entrada e a retornou sem a quebra de linha, então o programa imprimiu Next year you will be 37. Para várias perguntas, aguarde (await) um question() depois do outro.

question() do readline com callback

A API original, presente em todas as versões do Node.js, passa a resposta para um callback. Perguntas encadeadas viram callbacks aninhados:

Ele imprimiu o prompt, depois You picked blue. A resposta é uma string simples, então aplique trim antes de comparar: um usuário que digita um espaço depois da palavra acaba com 'blue ', que não é igual a 'blue'.

Ler a entrada linha por linha

Para processar cada linha até a entrada acabar, percorra a interface com for await. É assim que um programa lê uma lista digitada pelo usuário (encerrada com Ctrl+D) ou um arquivo enviado por pipe com node index.js < numbers.txt. Código mais antigo faz o mesmo com eventos, rl.on('line', fn) para cada linha e rl.on('close', fn) no final; o loop é esse par de eventos escrito de cima para baixo:

Ele imprimiu 3 numbers, total 49, e o loop terminou sozinho quando a entrada acabou, então não precisa de close(). Adicione uma quarta linha de entrada, 1, e o resultado vira 4 numbers, total 50.

Ler todo o stdin de uma vez

Para entrada que vem por pipe de outro programa (cat data.txt | node index.js), ler tudo em uma chamada é mais simples. O descritor de arquivo 0 é a entrada padrão. Um arquivo salvo no Windows pode terminar as linhas com \r\n, então divida com /\r?\n/ quando a entrada puder vir de lá:

Ele imprimiu os três itens em coluna. readFileSync(0) bloqueia até a entrada estar completa, o que serve para um script que lê um pipe e para testes, mas é errado para uma ferramenta interativa, em que o usuário teria que digitar tudo antes de ver qualquer prompt.

Qual usar

Os quatro leem a mesma entrada padrão. A diferença é quando seu código recebe o texto: uma resposta por vez, uma linha por vez ou tudo no final.

NecessidadeUse
Fazer algumas perguntas em ordemreadline/promises com await rl.question()
Suportar versões do Node.js anteriores à 17readline com callback em question()
Tratar cada linha conforme chegafor await (const line of rl)
Ler um pipe ou arquivo inteiro do stdinfs.readFileSync(0, 'utf8')
Valores conhecidos antes de o programa começarprocess.argv no lugar

Erros comuns

Esquecer o rl.close(). A interface mantém a entrada padrão aberta, então o programa nunca termina depois da última pergunta. Feche quando tiver todas as respostas.

Usar a resposta como número. Como tudo o que se digita em um terminal, a resposta é uma string. '36' + 1 é '361'; converta com Number() antes.

Mandar várias respostas por pipe para várias perguntas. Quando a entrada vem de um pipe e não do teclado, o readline lê tudo de uma vez, e uma linha que chega antes de o seu question() ser feito é descartada. Para entrada via pipe, use o loop for await ou readFileSync(0).

Deixar de fora a opção output. Sem output: process.stdout, question() nunca imprime o prompt, e o usuário fica olhando para um terminal vazio. O loop linha por linha não precisa dela, porque não imprime nada.

Perguntas frequentes

Por que prompt não está definido no Node.js?

prompt() é uma função do navegador que abre uma caixa de diálogo, e o Node.js não tem janela para abri-la. Use readline no Node.js, ou um pacote como prompts ou inquirer para menus e campos de senha.

Como ler uma senha sem mostrá-la?

O readline mostra cada tecla. Pacotes como prompts ou @inquirer/password mascaram a entrada; fazer você mesmo significa colocar o terminal em modo raw com process.stdin.setRawMode(true) e tratar cada tecla.

Devo usar readline ou process.argv?

Use process.argv quando os valores são conhecidos antes de o programa começar, assim ele roda em um script sem ninguém presente. Use readline para ferramentas interativas que fazem uma pergunta depois da outra.

Ilustração das linguagens de programação do Coddy

Aprenda a programar com o Coddy

Começar