Readline
소스 코드: lib/readline.js
node:readline
모듈은 Readable 스트림 (예: process.stdin
에서) 데이터를 한 번에 한 줄씩 읽기 위한 인터페이스를 제공합니다.
Promise 기반 API를 사용하려면:
import * as readline from 'node:readline/promises'
const readline = require('node:readline/promises')
콜백 및 동기 API를 사용하려면:
import * as readline from 'node:readline'
const readline = require('node:readline')
다음의 간단한 예제는 node:readline
모듈의 기본적인 사용법을 보여줍니다.
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('Node.js에 대해 어떻게 생각하십니까? ')
console.log(`소중한 피드백 감사합니다: ${answer}`)
rl.close()
const readline = require('node:readline')
const { stdin: input, stdout: output } = require('node:process')
const rl = readline.createInterface({ input, output })
rl.question('Node.js에 대해 어떻게 생각하십니까? ', answer => {
// TODO: 답변을 데이터베이스에 기록합니다.
console.log(`소중한 피드백 감사합니다: ${answer}`)
rl.close()
})
이 코드가 호출되면 인터페이스는 input
스트림에서 데이터를 수신하기를 기다리므로 readline.Interface
가 닫힐 때까지 Node.js 애플리케이션이 종료되지 않습니다.
클래스: InterfaceConstructor
추가된 버전: v0.1.104
- 확장: <EventEmitter>
InterfaceConstructor
클래스의 인스턴스는 readlinePromises.createInterface()
또는 readline.createInterface()
메서드를 사용하여 생성됩니다. 모든 인스턴스는 단일 input
Readable 스트림 및 단일 output
Writable 스트림과 연결됩니다. output
스트림은 input
스트림에 도착하여 읽은 사용자 입력에 대한 프롬프트를 인쇄하는 데 사용됩니다.
Event: 'close'
Added in: v0.1.98
다음 중 하나가 발생하면 'close'
이벤트가 발생합니다.
rl.close()
메서드가 호출되고InterfaceConstructor
인스턴스가input
및output
스트림에 대한 제어를 포기한 경우;input
스트림이'end'
이벤트를 수신한 경우;input
스트림이 전송 종료(EOT)를 나타내는 +를 수신한 경우;input
스트림이SIGINT
를 나타내는 +를 수신하고InterfaceConstructor
인스턴스에 등록된'SIGINT'
이벤트 리스너가 없는 경우.
리스너 함수는 인수를 전달하지 않고 호출됩니다.
'close'
이벤트가 발생하면 InterfaceConstructor
인스턴스가 완료됩니다.
Event: 'line'
Added in: v0.1.98
input
스트림이 줄 끝 입력(\n
, \r
또는 \r\n
)을 수신할 때마다 'line'
이벤트가 발생합니다. 이는 일반적으로 사용자가 또는 키를 누를 때 발생합니다.
스트림에서 새로운 데이터가 읽혀지고 해당 스트림이 최종 줄 끝 마커 없이 종료된 경우에도 'line'
이벤트가 발생합니다.
리스너 함수는 수신된 입력의 단일 줄을 포함하는 문자열과 함께 호출됩니다.
rl.on('line', input => {
console.log(`Received: ${input}`)
})
Event: 'history'
Added in: v15.8.0, v14.18.0
기록 배열이 변경될 때마다 'history'
이벤트가 발생합니다.
리스너 함수는 기록 배열을 포함하는 배열과 함께 호출됩니다. historySize
및 removeHistoryDuplicates
로 인해 추가된 줄과 제거된 줄을 포함한 모든 변경 사항이 반영됩니다.
주요 목적은 리스너가 기록을 유지할 수 있도록 하는 것입니다. 리스너가 기록 객체를 변경하는 것도 가능합니다. 이는 암호와 같은 특정 줄이 기록에 추가되는 것을 방지하는 데 유용할 수 있습니다.
rl.on('history', history => {
console.log(`Received: ${history}`)
})
Event: 'pause'
Added in: v0.7.5
다음 중 하나가 발생하면 'pause'
이벤트가 발생합니다.
리스너 함수는 인수를 전달하지 않고 호출됩니다.
rl.on('pause', () => {
console.log('Readline paused.')
})
Event: 'resume'
Added in: v0.7.5
'resume'
이벤트는 input
스트림이 재개될 때마다 발생합니다.
리스너 함수는 어떠한 인수도 전달받지 않고 호출됩니다.
rl.on('resume', () => {
console.log('Readline resumed.')
})
Event: 'SIGCONT'
Added in: v0.7.5
'SIGCONT'
이벤트는 이전에 + (즉, SIGTSTP
)를 사용하여 백그라운드로 이동한 Node.js 프로세스가 fg(1p)
를 사용하여 포그라운드로 다시 돌아올 때 발생합니다.
input
스트림이 SIGTSTP
요청 이전에 일시 중지된 경우, 이 이벤트는 발생하지 않습니다.
리스너 함수는 어떠한 인수도 전달받지 않고 호출됩니다.
rl.on('SIGCONT', () => {
// `prompt`는 스트림을 자동으로 재개합니다.
rl.prompt()
})
'SIGCONT'
이벤트는 Windows에서 지원되지 않습니다.
Event: 'SIGINT'
Added in: v0.3.0
'SIGINT'
이벤트는 input
스트림이 일반적으로 SIGINT
로 알려진 입력을 수신할 때마다 발생합니다. input
스트림이 SIGINT
를 수신할 때 등록된 'SIGINT'
이벤트 리스너가 없으면 'pause'
이벤트가 발생합니다.
리스너 함수는 어떠한 인수도 전달받지 않고 호출됩니다.
rl.on('SIGINT', () => {
rl.question('Are you sure you want to exit? ', answer => {
if (answer.match(/^y(es)?$/i)) rl.pause()
})
})
Event: 'SIGTSTP'
Added in: v0.7.5
'SIGTSTP'
이벤트는 input
스트림이 일반적으로 SIGTSTP
로 알려진 + 입력을 수신할 때 발생합니다. input
스트림이 SIGTSTP
를 수신할 때 등록된 'SIGTSTP'
이벤트 리스너가 없으면 Node.js 프로세스가 백그라운드로 보내집니다.
fg(1p)
를 사용하여 프로그램이 재개되면 'pause'
및 'SIGCONT'
이벤트가 발생합니다. 이들은 input
스트림을 재개하는 데 사용할 수 있습니다.
프로세스가 백그라운드로 보내지기 전에 input
이 일시 중지된 경우 'pause'
및 'SIGCONT'
이벤트는 발생하지 않습니다.
리스너 함수는 어떠한 인수도 전달받지 않고 호출됩니다.
rl.on('SIGTSTP', () => {
// 이는 SIGTSTP를 재정의하고 프로그램이 백그라운드로 가는 것을 방지합니다.
console.log('Caught SIGTSTP.')
})
'SIGTSTP'
이벤트는 Windows에서 지원되지 않습니다.
rl.close()
추가된 버전: v0.1.98
rl.close()
메서드는 InterfaceConstructor
인스턴스를 닫고 input
및 output
스트림에 대한 제어를 포기합니다. 호출되면 'close'
이벤트가 발생합니다.
rl.close()
를 호출해도 InterfaceConstructor
인스턴스에서 다른 이벤트('line'
포함)가 즉시 발생하는 것을 멈추지는 않습니다.
rl.pause()
추가된 버전: v0.3.4
rl.pause()
메서드는 input
스트림을 일시 중지하여 필요한 경우 나중에 다시 시작할 수 있도록 합니다.
rl.pause()
를 호출해도 InterfaceConstructor
인스턴스에서 다른 이벤트('line'
포함)가 즉시 발생하는 것을 멈추지는 않습니다.
rl.prompt([preserveCursor])
추가된 버전: v0.1.98
preserveCursor
<boolean>true
이면 커서 위치가0
으로 재설정되는 것을 방지합니다.
rl.prompt()
메서드는 사용자에게 입력을 제공할 새로운 위치를 제공하기 위해 InterfaceConstructor
인스턴스에 구성된 prompt
를 output
의 새 줄에 씁니다.
호출되면 rl.prompt()
는 일시 중지된 경우 input
스트림을 다시 시작합니다.
InterfaceConstructor
가 output
을 null
또는 undefined
로 설정하여 생성된 경우 프롬프트가 기록되지 않습니다.
rl.resume()
추가된 버전: v0.3.4
rl.resume()
메서드는 일시 중지된 경우 input
스트림을 다시 시작합니다.
rl.setPrompt(prompt)
추가된 버전: v0.1.98
prompt
<string>
rl.setPrompt()
메서드는 rl.prompt()
가 호출될 때마다 output
에 기록될 프롬프트를 설정합니다.
rl.getPrompt()
추가된 버전: v15.3.0, v14.17.0
- 반환값: <string> 현재 프롬프트 문자열
rl.getPrompt()
메서드는 rl.prompt()
에서 사용하는 현재 프롬프트를 반환합니다.
rl.write(data[, key])
추가된 버전: v0.1.98
rl.write()
메서드는 data
또는 key
로 식별된 키 시퀀스를 output
에 씁니다. key
인수는 output
이 TTY 텍스트 터미널인 경우에만 지원됩니다. 키 조합 목록은 TTY 키 바인딩을 참조하십시오.
key
가 지정되면 data
는 무시됩니다.
호출되면 rl.write()
는 일시 중지된 경우 input
스트림을 다시 시작합니다.
InterfaceConstructor
가 output
을 null
또는 undefined
로 설정하여 생성된 경우 data
및 key
는 기록되지 않습니다.
rl.write('이거 삭제해!')
// 이전에 쓴 줄을 삭제하기 위해 Ctrl+U를 시뮬레이션합니다.
rl.write(null, { ctrl: true, name: 'u' })
rl.write()
메서드는 readline
Interface
의 input
에 데이터를 마치 사용자가 제공한 것처럼 씁니다.
rl[Symbol.asyncIterator]()
[기록]
버전 | 변경 사항 |
---|---|
v11.14.0, v10.17.0 | Symbol.asyncIterator 지원이 더 이상 실험적이지 않습니다. |
v11.4.0, v10.16.0 | 추가됨: v11.4.0, v10.16.0 |
- 반환 값: <AsyncIterator>
입력 스트림의 각 라인을 문자열로 반복하는 AsyncIterator
객체를 생성합니다. 이 메서드를 사용하면 for await...of
루프를 통해 InterfaceConstructor
객체를 비동기적으로 반복할 수 있습니다.
입력 스트림의 오류는 전달되지 않습니다.
루프가 break
, throw
또는 return
으로 종료되면 rl.close()
가 호출됩니다. 즉, InterfaceConstructor
를 반복하면 항상 입력 스트림을 완전히 소비합니다.
성능은 기존의 'line'
이벤트 API와 동등하지 않습니다. 성능에 민감한 애플리케이션에는 'line'
을 대신 사용하십시오.
async function processLineByLine() {
const rl = readline.createInterface({
// ...
})
for await (const line of rl) {
// readline 입력의 각 라인이 여기에서 `line`으로 연속적으로 사용 가능합니다.
}
}
readline.createInterface()
는 호출되면 입력 스트림을 소비하기 시작합니다. 인터페이스 생성과 비동기적 반복 사이에 비동기 작업이 있으면 누락된 라인이 발생할 수 있습니다.
rl.line
[기록]
버전 | 변경 사항 |
---|---|
v15.8.0, v14.18.0 | 값은 항상 문자열이며 정의되지 않습니다. |
v0.1.98 | 추가됨: v0.1.98 |
node에서 현재 처리 중인 입력 데이터입니다.
이것은 TTY 스트림에서 입력을 수집할 때 line
이벤트가 발생하기 전에 지금까지 처리된 현재 값을 검색하는 데 사용할 수 있습니다. line
이벤트가 발생하면 이 속성은 빈 문자열이 됩니다.
인스턴스 런타임 중에 값을 수정하면 rl.cursor
도 제어하지 않는 경우 의도하지 않은 결과가 발생할 수 있습니다.
입력에 TTY 스트림을 사용하지 않는 경우 'line'
이벤트를 사용하십시오.
가능한 사용 사례는 다음과 같습니다.
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
추가된 버전: v0.1.98
rl.line
을 기준으로 한 커서 위치입니다.
이는 TTY 스트림에서 입력을 읽을 때 현재 커서가 입력 문자열 내에서 어디에 있는지 추적합니다. 커서의 위치는 입력이 처리됨에 따라 수정될 입력 문자열의 부분과 터미널 캐럿이 렌더링될 열을 결정합니다.
rl.getCursorPos()
추가된 버전: v13.5.0, v12.16.0
입력 프롬프트 + 문자열과 관련된 커서의 실제 위치를 반환합니다. 긴 입력(줄 바꿈) 문자열과 여러 줄 프롬프트가 계산에 포함됩니다.
Promises API
추가된 버전: v17.0.0
클래스: readlinePromises.Interface
추가된 버전: v17.0.0
readlinePromises.Interface
클래스의 인스턴스는 readlinePromises.createInterface()
메서드를 사용하여 생성됩니다. 모든 인스턴스는 단일 input
Readable 스트림과 단일 output
Writable 스트림과 연결됩니다. output
스트림은 input
스트림에 도착하여 읽는 사용자 입력에 대한 프롬프트를 인쇄하는 데 사용됩니다.
rl.question(query[, options])
추가된 버전: v17.0.0
query
<string>output
에 쓰여질 문장 또는 쿼리이며, 프롬프트 앞에 붙습니다.options
<Object>signal
<AbortSignal> 선택적으로AbortSignal
을 사용하여question()
을 취소할 수 있습니다.
반환값: <Promise>
query
에 대한 응답으로 사용자의 입력을 담은 프로미스가 이행됩니다.
rl.question()
메서드는 output
에 작성하여 query
를 표시하고, input
에 사용자 입력이 제공되기를 기다린 다음, 제공된 입력을 첫 번째 인수로 전달하여 callback
함수를 호출합니다.
호출되면 rl.question()
은 일시 중지된 경우 input
스트림을 재개합니다.
readlinePromises.Interface
가 output
이 null
또는 undefined
로 설정된 상태로 생성된 경우 query
는 작성되지 않습니다.
rl.close()
이후에 질문이 호출되면 거부된 프로미스를 반환합니다.
사용 예시:
const answer = await rl.question('가장 좋아하는 음식은 무엇인가요? ')
console.log(`아, 가장 좋아하는 음식이 ${answer}이군요`)
AbortSignal
을 사용하여 질문을 취소합니다.
const signal = AbortSignal.timeout(10_000)
signal.addEventListener(
'abort',
() => {
console.log('음식 질문 시간이 초과되었습니다.')
},
{ once: true }
)
const answer = await rl.question('가장 좋아하는 음식은 무엇인가요? ', { signal })
console.log(`아, 가장 좋아하는 음식이 ${answer}이군요`)
Class: readlinePromises.Readline
추가된 버전: v17.0.0
new readlinePromises.Readline(stream[, options])
추가된 버전: v17.0.0
stream
<stream.Writable> TTY 스트림입니다.options
<Object>autoCommit
<boolean>true
이면rl.commit()
을 호출할 필요가 없습니다.
rl.clearLine(dir)
v17.0.0에 추가됨
dir
<정수>-1
: 커서 왼쪽1
: 커서 오른쪽0
: 전체 줄
반환: this
rl.clearLine()
메서드는 dir
로 식별되는 지정된 방향으로 연결된 stream
의 현재 줄을 지우는 작업을 보류 중인 작업 내부 목록에 추가합니다. 생성자에 autoCommit: true
가 전달되지 않은 경우, 이 메서드의 효과를 보려면 rl.commit()
을 호출하세요.
rl.clearScreenDown()
v17.0.0에 추가됨
- 반환: this
rl.clearScreenDown()
메서드는 커서의 현재 위치부터 연결된 스트림 아래를 지우는 작업을 보류 중인 작업 내부 목록에 추가합니다. 생성자에 autoCommit: true
가 전달되지 않은 경우, 이 메서드의 효과를 보려면 rl.commit()
을 호출하세요.
rl.commit()
v17.0.0에 추가됨
- 반환: <Promise>
rl.commit()
메서드는 보류 중인 모든 작업을 연결된 stream
으로 보내고 보류 중인 작업 내부 목록을 지웁니다.
rl.cursorTo(x[, y])
v17.0.0에 추가됨
rl.cursorTo()
메서드는 연결된 stream
에서 지정된 위치로 커서를 이동하는 작업을 보류 중인 작업 내부 목록에 추가합니다. 생성자에 autoCommit: true
가 전달되지 않은 경우, 이 메서드의 효과를 보려면 rl.commit()
을 호출하세요.
rl.moveCursor(dx, dy)
v17.0.0에 추가됨
rl.moveCursor()
메서드는 연결된 stream
에서 현재 커서 위치를 기준으로 커서를 상대적으로 이동하는 작업을 보류 중인 작업 내부 목록에 추가합니다. 생성자에 autoCommit: true
가 전달되지 않은 경우, 이 메서드의 효과를 보려면 rl.commit()
을 호출하세요.
rl.rollback()
추가된 버전: v17.0.0
- 반환 값: this
rl.rollback
메서드는 연결된 stream
으로 보내지 않고 보류 중인 작업의 내부 목록을 지웁니다.
readlinePromises.createInterface(options)
추가된 버전: v17.0.0
options
<Object>input
<stream.Readable> 수신할 Readable 스트림입니다. 이 옵션은 필수입니다.output
<stream.Writable> readline 데이터를 쓸 Writable 스트림입니다.completer
<Function> 탭 자동 완성에 사용되는 선택적 함수입니다.terminal
<boolean>input
및output
스트림을 TTY처럼 처리하고 ANSI/VT100 이스케이프 코드를 쓸지 여부입니다. 기본값: 인스턴스화 시output
스트림에서isTTY
를 확인합니다.history
<string[]> 기록 줄의 초기 목록입니다. 이 옵션은 사용자가terminal
을true
로 설정하거나 내부output
확인을 통해서만 의미가 있습니다. 그렇지 않으면 기록 캐싱 메커니즘이 초기화되지 않습니다. 기본값:[]
.historySize
<number> 유지되는 최대 기록 줄 수입니다. 기록을 비활성화하려면 이 값을0
으로 설정하십시오. 이 옵션은 사용자가terminal
을true
로 설정하거나 내부output
확인을 통해서만 의미가 있습니다. 그렇지 않으면 기록 캐싱 메커니즘이 초기화되지 않습니다. 기본값:30
.removeHistoryDuplicates
<boolean>true
인 경우 기록 목록에 추가된 새 입력 줄이 이전 줄과 중복되면 이전 줄이 목록에서 제거됩니다. 기본값:false
.prompt
<string> 사용할 프롬프트 문자열입니다. 기본값:'\> '
.crlfDelay
<number>\r
과\n
사이의 지연 시간이crlfDelay
밀리초를 초과하면\r
과\n
이 별도의 줄 끝 입력으로 처리됩니다.crlfDelay
는100
이상 숫자로 강제 변환됩니다.Infinity
로 설정할 수 있으며, 이 경우\r
다음에\n
이 오면 항상 단일 줄 바꿈으로 간주됩니다(이는\r\n
줄 구분 기호로 파일을 읽는 경우에 합리적일 수 있습니다). 기본값:100
.escapeCodeTimeout
<number>readlinePromises
가 문자를 기다리는 시간(밀리초 단위로 지금까지 읽은 입력을 사용하여 전체 키 시퀀스를 형성할 수 있고 더 긴 키 시퀀스를 완료하기 위해 추가 입력을 받을 수 있는 모호한 키 시퀀스를 읽을 때)입니다. 기본값:500
.tabSize
<integer> 탭이 나타내는 공백 수(최소 1). 기본값:8
.
readlinePromises.createInterface()
메서드는 새로운 readlinePromises.Interface
인스턴스를 만듭니다.
import { createInterface } from 'node:readline/promises'
import { stdin, stdout } from 'node:process'
const rl = createInterface({
input: stdin,
output: stdout,
})
const { createInterface } = require('node:readline/promises')
const rl = createInterface({
input: process.stdin,
output: process.stdout,
})
readlinePromises.Interface
인스턴스가 생성되면 가장 일반적인 경우는 'line'
이벤트를 수신하는 것입니다.
rl.on('line', line => {
console.log(`받음: ${line}`)
})
이 인스턴스에 대해 terminal
이 true
이면 output
스트림은 output.columns
속성을 정의하고 열이 변경될 경우 output
에 'resize'
이벤트를 발생시키면 가장 잘 호환됩니다(process.stdout
는 TTY일 때 자동으로 수행합니다).
completer
함수 사용
completer
함수는 사용자가 입력한 현재 줄을 인수로 받아, 두 개의 항목으로 구성된 Array
를 반환합니다.
- 완성에 맞는 항목이 포함된
Array
- 매칭에 사용된 부분 문자열
예: [[substr1, substr2, ...], originalsubstring]
.
function completer(line) {
const completions = '.help .error .exit .quit .q'.split(' ')
const hits = completions.filter(c => c.startsWith(line))
// 찾은 항목이 없으면 모든 완성 항목 표시
return [hits.length ? hits : completions, line]
}
completer
함수는 <Promise>를 반환하거나 비동기적일 수도 있습니다.
async function completer(linePartial) {
await someAsyncWork()
return [['123'], linePartial]
}
콜백 API
추가된 버전: v0.1.104
클래스: readline.Interface
[기록]
버전 | 변경 사항 |
---|---|
v17.0.0 | readline.Interface 클래스가 이제 Interface 에서 상속합니다. |
v0.1.104 | 추가된 버전: v0.1.104 |
readline.Interface
클래스의 인스턴스는 readline.createInterface()
메서드를 사용하여 생성됩니다. 모든 인스턴스는 단일 input
Readable 스트림과 단일 output
Writable 스트림과 연결됩니다. output
스트림은 input
스트림으로 들어와 읽은 사용자 입력에 대한 프롬프트를 출력하는 데 사용됩니다.
rl.question(query[, options], callback)
추가된 버전: v0.3.3
query
<string> 프롬프트 앞에 추가되어output
에 출력할 구문 또는 쿼리.options
<Object>signal
<AbortSignal> 선택적으로AbortController
를 사용하여question()
을 취소할 수 있습니다.
callback
<Function>query
에 대한 응답으로 사용자의 입력을 사용하여 호출되는 콜백 함수.
rl.question()
메서드는 output
에 query
를 출력하여 표시하고, input
에서 사용자 입력이 제공되기를 기다린 다음, 제공된 입력을 첫 번째 인수로 전달하여 callback
함수를 호출합니다.
호출 시 rl.question()
은 일시 중지된 경우 input
스트림을 다시 시작합니다.
readline.Interface
가 output
을 null
또는 undefined
로 설정하여 생성된 경우 query
는 작성되지 않습니다.
rl.question()
에 전달된 callback
함수는 첫 번째 인수로 Error
객체나 null
을 허용하는 일반적인 패턴을 따르지 않습니다. callback
은 제공된 답변을 유일한 인수로 호출됩니다.
rl.close()
이후 rl.question()
을 호출하면 오류가 발생합니다.
사용 예:
rl.question('가장 좋아하는 음식이 무엇인가요? ', answer => {
console.log(`아, 당신이 가장 좋아하는 음식은 ${answer}군요`)
})
AbortController
를 사용하여 질문을 취소합니다.
const ac = new AbortController()
const signal = ac.signal
rl.question('가장 좋아하는 음식이 무엇인가요? ', { signal }, answer => {
console.log(`아, 당신이 가장 좋아하는 음식은 ${answer}군요`)
})
signal.addEventListener(
'abort',
() => {
console.log('음식 질문 시간이 초과되었습니다.')
},
{ once: true }
)
setTimeout(() => ac.abort(), 10000)
readline.clearLine(stream, dir[, callback])
[History]
버전 | 변경 사항 |
---|---|
v18.0.0 | callback 인수에 유효하지 않은 콜백을 전달하면 이제 ERR_INVALID_CALLBACK 대신 ERR_INVALID_ARG_TYPE 이 발생합니다. |
v12.7.0 | 스트림의 write() 콜백과 반환 값이 노출됩니다. |
v0.7.7 | 추가됨: v0.7.7 |
stream
<stream.Writable>dir
<number>-1
: 커서 왼쪽1
: 커서 오른쪽0
: 전체 라인
callback
<Function> 작업이 완료되면 호출됩니다.- 반환 값: <boolean>
stream
이 추가 데이터를 쓰기 전에 호출 코드가'drain'
이벤트가 발생하기를 기다리기를 원하는 경우false
이고, 그렇지 않으면true
입니다.
readline.clearLine()
메서드는 dir
로 지정된 방향으로 주어진 TTY 스트림의 현재 라인을 지웁니다.
readline.clearScreenDown(stream[, callback])
[History]
버전 | 변경 사항 |
---|---|
v18.0.0 | callback 인수에 유효하지 않은 콜백을 전달하면 이제 ERR_INVALID_CALLBACK 대신 ERR_INVALID_ARG_TYPE 이 발생합니다. |
v12.7.0 | 스트림의 write() 콜백과 반환 값이 노출됩니다. |
v0.7.7 | 추가됨: v0.7.7 |
stream
<stream.Writable>callback
<Function> 작업이 완료되면 호출됩니다.- 반환 값: <boolean>
stream
이 추가 데이터를 쓰기 전에 호출 코드가'drain'
이벤트가 발생하기를 기다리기를 원하는 경우false
이고, 그렇지 않으면true
입니다.
readline.clearScreenDown()
메서드는 커서의 현재 위치부터 아래로 주어진 TTY 스트림을 지웁니다.
readline.createInterface(options)
[History]
버전 | 변경 사항 |
---|---|
v15.14.0, v14.18.0 | signal 옵션이 지원됩니다. |
v15.8.0, v14.18.0 | history 옵션이 지원됩니다. |
v13.9.0 | tabSize 옵션이 지원됩니다. |
v8.3.0, v6.11.4 | crlfDelay 옵션의 최대 제한이 제거되었습니다. |
v6.6.0 | crlfDelay 옵션이 지원됩니다. |
v6.3.0 | prompt 옵션이 지원됩니다. |
v6.0.0 | historySize 옵션이 이제 0 일 수 있습니다. |
v0.1.98 | 추가됨: v0.1.98 |
options
<Object>input
<stream.Readable> 수신할 Readable 스트림입니다. 이 옵션은 필수입니다.output
<stream.Writable> readline 데이터를 쓸 Writable 스트림입니다.completer
<Function> 탭 자동 완성에 사용되는 선택적 함수입니다.terminal
<boolean>input
및output
스트림을 TTY처럼 취급하고 ANSI/VT100 이스케이프 코드를 쓸지 여부입니다. 기본값: 인스턴스화 시output
스트림에서isTTY
를 확인합니다.history
<string[]> 히스토리 라인의 초기 목록입니다. 이 옵션은 사용자가terminal
을true
로 설정하거나 내부output
검사를 통해true
로 설정된 경우에만 의미가 있습니다. 그렇지 않으면 히스토리 캐싱 메커니즘이 전혀 초기화되지 않습니다. 기본값:[]
.historySize
<number> 보관되는 최대 히스토리 라인 수입니다. 히스토리를 비활성화하려면 이 값을0
으로 설정하세요. 이 옵션은 사용자가terminal
을true
로 설정하거나 내부output
검사를 통해true
로 설정된 경우에만 의미가 있습니다. 그렇지 않으면 히스토리 캐싱 메커니즘이 전혀 초기화되지 않습니다. 기본값:30
.removeHistoryDuplicates
<boolean>true
인 경우, 히스토리 목록에 새 입력 라인이 추가될 때 이전 라인과 중복되면 목록에서 이전 라인을 제거합니다. 기본값:false
.prompt
<string> 사용할 프롬프트 문자열입니다. 기본값:'\> '
.crlfDelay
<number>\r
과\n
사이의 지연 시간이crlfDelay
밀리초를 초과하면\r
과\n
이 별도의 줄 끝 입력으로 처리됩니다.crlfDelay
는100
이상인 숫자로 강제 변환됩니다.Infinity
로 설정할 수 있으며, 이 경우\r
다음에\n
이 오는 경우는 항상 단일 줄 바꿈으로 간주됩니다. 이는\r\n
줄 구분 기호를 사용하여 파일 읽기에 적합할 수 있습니다. 기본값:100
.escapeCodeTimeout
<number>readline
이 모호한 키 시퀀스(지금까지 읽은 입력을 사용하여 완전한 키 시퀀스를 형성할 수 있고 더 긴 키 시퀀스를 완료하기 위해 추가 입력을 받을 수 있는 시퀀스)를 읽을 때 문자를 기다리는 시간(밀리초)입니다. 기본값:500
.tabSize
<integer> 탭이 나타내는 공백 수입니다(최소 1). 기본값:8
.signal
<AbortSignal> AbortSignal을 사용하여 인터페이스를 닫을 수 있습니다. 신호를 중단하면 인터페이스에서 내부적으로close
를 호출합니다.
readline.createInterface()
메서드는 새 readline.Interface
인스턴스를 만듭니다.
import { createInterface } from 'node:readline'
import { stdin, stdout } from 'node:process'
const rl = createInterface({
input: stdin,
output: stdout,
})
const { createInterface } = require('node:readline')
const rl = createInterface({
input: process.stdin,
output: process.stdout,
})
readline.Interface
인스턴스가 생성되면 가장 일반적인 경우는 'line'
이벤트 수신입니다.
rl.on('line', line => {
console.log(`Received: ${line}`)
})
이 인스턴스에 대해 terminal
이 true
이면 output
스트림이 output.columns
속성을 정의하고 열이 변경될 때마다 output
에 'resize'
이벤트를 발생시키면 최상의 호환성을 얻을 수 있습니다(process.stdout
은 TTY일 때 자동으로 이 작업을 수행합니다).
stdin
을 입력으로 사용하여 readline.Interface
를 생성할 때 프로그램은 EOF 문자를 수신할 때까지 종료되지 않습니다. 사용자 입력을 기다리지 않고 종료하려면 process.stdin.unref()
를 호출하세요.
completer
함수의 사용
completer
함수는 사용자가 입력한 현재 줄을 인수로 받아들이고, 두 개의 항목이 있는 Array
를 반환합니다.
- 자동 완성에 일치하는 항목을 포함하는
Array
. - 일치에 사용된 하위 문자열.
예를 들어: [[substr1, substr2, ...], originalsubstring]
.
function completer(line) {
const completions = '.help .error .exit .quit .q'.split(' ')
const hits = completions.filter(c => c.startsWith(line))
// 찾은 것이 없으면 모든 자동 완성 표시
return [hits.length ? hits : completions, line]
}
completer
함수는 두 개의 인수를 허용하는 경우 비동기적으로 호출할 수 있습니다.
function completer(linePartial, callback) {
callback(null, [['123'], linePartial])
}
readline.cursorTo(stream, x[, y][, callback])
[기록]
버전 | 변경 사항 |
---|---|
v18.0.0 | callback 인수에 잘못된 콜백을 전달하면 이제 ERR_INVALID_CALLBACK 대신 ERR_INVALID_ARG_TYPE 이 발생합니다. |
v12.7.0 | 스트림의 write() 콜백 및 반환 값이 노출됩니다. |
v0.7.7 | v0.7.7에서 추가됨 |
stream
<stream.Writable>x
<number>y
<number>callback
<Function> 작업이 완료되면 호출됩니다.- 반환 값: <boolean>
stream
이 추가 데이터를 계속 쓰기 전에 호출 코드가'drain'
이벤트가 발생하기를 기다리도록 하려는 경우false
; 그렇지 않으면true
.
readline.cursorTo()
메서드는 주어진 TTY stream
에서 커서를 지정된 위치로 이동합니다.
readline.moveCursor(stream, dx, dy[, callback])
[기록]
버전 | 변경 사항 |
---|---|
v18.0.0 | callback 인수에 잘못된 콜백을 전달하면 이제 ERR_INVALID_CALLBACK 대신 ERR_INVALID_ARG_TYPE 이 발생합니다. |
v12.7.0 | 스트림의 write() 콜백 및 반환 값이 노출됩니다. |
v0.7.7 | v0.7.7에서 추가됨 |
stream
<stream.Writable>dx
<number>dy
<number>callback
<Function> 작업이 완료되면 호출됩니다.- 반환 값: <boolean>
stream
이 추가 데이터를 계속 쓰기 전에 호출 코드가'drain'
이벤트가 발생하기를 기다리도록 하려는 경우false
; 그렇지 않으면true
.
readline.moveCursor()
메서드는 주어진 TTY stream
에서 현재 위치를 기준으로 커서를 이동합니다.
readline.emitKeypressEvents(stream[, interface])
추가된 버전: v0.7.7
stream
<stream.Readable>interface
<readline.InterfaceConstructor>
readline.emitKeypressEvents()
메서드는 주어진 Readable 스트림이 수신된 입력에 해당하는 'keypress'
이벤트를 방출하기 시작하도록 합니다.
선택적으로 interface
는 복사 붙여넣기된 입력이 감지될 때 자동 완성이 비활성화되는 readline.Interface
인스턴스를 지정합니다.
stream
이 TTY인 경우, 원시 모드여야 합니다.
이는 input
이 터미널인 경우 input
에서 모든 readline 인스턴스에 의해 자동으로 호출됩니다. readline
인스턴스를 닫아도 input
이 'keypress'
이벤트를 방출하는 것을 멈추지 않습니다.
readline.emitKeypressEvents(process.stdin)
if (process.stdin.isTTY) process.stdin.setRawMode(true)
예시: Tiny CLI
다음 예시는 작은 명령줄 인터페이스를 구현하기 위해 readline.Interface
클래스를 사용하는 방법을 보여줍니다.
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)
})
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)
})
예제: 파일 스트림을 한 줄씩 읽기
readline
의 일반적인 사용 사례는 입력 파일을 한 번에 한 줄씩 소비하는 것입니다. 가장 쉬운 방법은 fs.ReadStream
API와 for await...of
루프를 활용하는 것입니다.
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,
})
// 참고: 입력.txt에서 CR LF ('\r\n')의 모든 인스턴스를 단일 줄 바꿈으로 인식하기 위해 crlfDelay 옵션을 사용합니다.
for await (const line of rl) {
// 입력.txt의 각 줄은 여기에서 `line`으로 순차적으로 사용할 수 있습니다.
console.log(`파일에서 온 줄: ${line}`)
}
}
processLineByLine()
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,
})
// 참고: 입력.txt에서 CR LF ('\r\n')의 모든 인스턴스를 단일 줄 바꿈으로 인식하기 위해 crlfDelay 옵션을 사용합니다.
for await (const line of rl) {
// 입력.txt의 각 줄은 여기에서 `line`으로 순차적으로 사용할 수 있습니다.
console.log(`파일에서 온 줄: ${line}`)
}
}
processLineByLine()
또는 'line'
이벤트를 사용할 수 있습니다.
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}`)
})
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}`)
})
현재 for await...of
루프는 약간 느릴 수 있습니다. async
/ await
흐름과 속도 모두 중요한 경우 혼합된 접근 방식을 적용할 수 있습니다.
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 => {
// 줄 처리
})
await once(rl, 'close')
console.log('파일 처리됨.')
} catch (err) {
console.error(err)
}
})()
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 => {
// 줄 처리
})
await once(rl, 'close')
console.log('파일 처리됨.')
} catch (err) {
console.error(err)
}
})()
TTY 키 바인딩
키 바인딩 | 설명 | 참고 |
---|---|---|
+ + | 왼쪽 줄 삭제 | Linux, Mac 및 Windows에서는 작동하지 않음 |
+ + | 오른쪽 줄 삭제 | Mac에서는 작동하지 않음 |
+ | SIGINT 발행 또는 readline 인스턴스 닫기 | |
+ | 왼쪽 삭제 | |
+ | 오른쪽 삭제 또는 현재 줄이 비어 있거나 EOF인 경우 readline 인스턴스 닫기 | Windows에서는 작동하지 않음 |
+ | 현재 위치에서 줄 시작까지 삭제 | |
+ | 현재 위치에서 줄 끝까지 삭제 | |
+ | 이전에 삭제된 텍스트 복원 (Yank) | + 또는 + 로 삭제한 텍스트에만 작동 |
+ | 이전에 삭제된 텍스트 간 순환 | 마지막 키 입력이 + 또는 + 인 경우에만 사용 가능 |
+ | 줄 시작으로 이동 | |
+ | 줄 끝으로 이동 | |
+ | 한 글자 뒤로 | |
+ | 한 글자 앞으로 | |
+ | 화면 지우기 | |
+ | 다음 히스토리 항목 | |
+ | 이전 히스토리 항목 | |
+ | 이전 변경 사항 실행 취소 | 키 코드 0x1F 를 발행하는 모든 키 입력이 이 작업을 수행합니다. 많은 터미널(예: xterm )에서 + 에 바인딩되어 있습니다. |
+ | 이전 변경 사항 다시 실행 | 많은 터미널에 기본 다시 실행 키 입력이 없습니다. 다시 실행을 수행하기 위해 키 코드 0x1E 를 선택합니다. xterm 에서 기본적으로 + 에 바인딩되어 있습니다. |
+ | 실행 중인 프로세스를 백그라운드로 이동합니다. fg 를 입력하고 를 눌러 돌아갑니다. | Windows에서는 작동하지 않음 |
+ 또는 + | 단어 경계까지 뒤로 삭제 | + 는 Linux, Mac 및 Windows에서는 작동하지 않음 |
+ | 단어 경계까지 앞으로 삭제 | Mac에서는 작동하지 않음 |
+ 또는 + | 왼쪽 단어 | + 는 Mac에서는 작동하지 않음 |
+ 또는 + | 오른쪽 단어 | + 는 Mac에서는 작동하지 않음 |
+ 또는 + | 오른쪽 단어 삭제 | + 는 Windows에서는 작동하지 않음 |
+ | 왼쪽 단어 삭제 | Mac에서는 작동하지 않음 |