Readline#

稳定性:2 - 稳定

源代码: lib/readline.js

node:readline 模块提供了一个接口,用于从 可读 流(例如 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('What do you think of Node.js? ');

console.log(`Thank you for your valuable feedback: ${answer}`);

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

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

rl.question('What do you think of Node.js? ', (answer) => {
  // TODO: Log the answer in a database
  console.log(`Thank you for your valuable feedback: ${answer}`);

  rl.close();
});

一旦此代码被调用,Node.js 应用程序将不会终止,直到 readline.Interface 关闭,因为该接口等待从 input 流接收数据。

类:InterfaceConstructor#

InterfaceConstructor 类实例是使用 readlinePromises.createInterface()readline.createInterface() 方法构造的。每个实例都与一个 input 可读 流和一个 output 可写 流相关联。output 流用于打印用户输入的提示,这些提示来自 input 流并从 input 流读取。

事件:'close'#

当以下情况之一发生时,将发出 'close' 事件

  • 调用 rl.close() 方法,InterfaceConstructor 实例放弃对 inputoutput 流的控制;
  • input 流接收其 'end' 事件;
  • input 流接收 Ctrl+D 以指示传输结束 (EOT);
  • input 流接收 Ctrl+C 以指示 SIGINT,并且 InterfaceConstructor 实例上没有注册 'SIGINT' 事件监听器。

监听器函数在不传递任何参数的情况下被调用。

一旦 'close' 事件被发出,InterfaceConstructor 实例就完成了。

事件:'line'#

每当 input 流接收行尾输入 (\n\r\r\n) 时,就会发出 'line' 事件。这通常发生在用户按下 EnterReturn 时。

如果从流中读取了新数据,并且该流在没有最终行尾标记的情况下结束,也会发出 'line' 事件。

监听器函数将被调用,并带有一个包含接收到的单行输入的字符串。

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

事件:'history'#

每当历史记录数组发生变化时,就会发出 'history' 事件。

监听器函数将被调用,并带有一个包含历史记录数组的数组。它将反映所有更改,包括由于 historySizeremoveHistoryDuplicates 添加的行和删除的行。

主要目的是允许监听器持久化历史记录。监听器也可以更改历史记录对象。这对于防止某些行(例如密码)添加到历史记录中可能很有用。

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

事件:'pause'#

当以下情况之一发生时,将发出 'pause' 事件

  • input 流被暂停。
  • input 流未被暂停,并接收 'SIGCONT' 事件。(参见事件 'SIGTSTP''SIGCONT'。)

监听器函数在不传递任何参数的情况下被调用。

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

事件: 'resume'#

input 流恢复时,会发出 'resume' 事件。

监听器函数在不传递任何参数的情况下被调用。

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

事件: 'SIGCONT'#

当之前使用 Ctrl+Z(即 SIGTSTP)移至后台的 Node.js 进程使用 fg(1p) 恢复到前台时,会发出 'SIGCONT' 事件。

如果 input 流在 SIGTSTP 请求之前被暂停,则不会发出此事件。

监听器函数在不传递任何参数的情况下被调用。

rl.on('SIGCONT', () => {
  // `prompt` will automatically resume the stream
  rl.prompt();
}); 

'SIGCONT' 事件不支持 Windows。

事件: 'SIGINT'#

input 流接收到 Ctrl+C 输入(通常称为 SIGINT)时,会发出 '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();
  });
}); 

事件: 'SIGTSTP'#

input 流接收到 Ctrl+Z 输入(通常称为 SIGTSTP)时,会发出 'SIGTSTP' 事件。如果在 input 流接收到 SIGTSTP 时没有注册 'SIGTSTP' 事件监听器,则 Node.js 进程将被发送到后台。

当使用 fg(1p) 恢复程序时,将发出 'pause''SIGCONT' 事件。这些事件可用于恢复 input 流。

如果 input 在进程被发送到后台之前被暂停,则不会发出 'pause''SIGCONT' 事件。

监听器函数在不传递任何参数的情况下被调用。

rl.on('SIGTSTP', () => {
  // This will override SIGTSTP and prevent the program from going to the
  // background.
  console.log('Caught SIGTSTP.');
}); 

'SIGTSTP' 事件不支持 Windows。

rl.close()#

rl.close() 方法关闭 InterfaceConstructor 实例并放弃对 inputoutput 流的控制。调用时,将发出 'close' 事件。

调用 rl.close() 不会立即停止 InterfaceConstructor 实例发出其他事件(包括 'line')。

rl.pause()#

rl.pause() 方法会暂停 input 流,允许在需要时恢复。

调用 rl.pause() 不会立即暂停其他事件(包括 'line')从 InterfaceConstructor 实例发出。

rl.prompt([preserveCursor])#

  • preserveCursor <boolean> 如果为 true,则防止光标位置重置为 0

rl.prompt() 方法将 InterfaceConstructor 实例配置的 prompt 写入 output 中的新行,以便为用户提供一个新的位置来输入。

调用 rl.prompt() 时,如果 input 流已暂停,则会恢复该流。

如果 InterfaceConstructor 是使用 output 设置为 nullundefined 创建的,则不会写入提示。

rl.resume()#

rl.resume() 方法会恢复 input 流,如果它已被暂停。

rl.setPrompt(prompt)#

rl.setPrompt() 方法设置每次调用 rl.prompt() 时将写入 output 的提示。

rl.getPrompt()#

  • 返回:<string> 当前提示字符串

rl.getPrompt() 方法返回 rl.prompt() 使用的当前提示。

rl.write(data[, key])#

rl.write() 方法将 data 或由 key 标识的键序列写入 outputkey 参数仅在 outputTTY 文本终端时才受支持。有关键组合列表,请参见 TTY 键绑定

如果指定了 key,则忽略 data

调用时,rl.write() 将恢复 input 流(如果它已被暂停)。

如果 InterfaceConstructor 是使用 output 设置为 nullundefined 创建的,则不会写入 datakey

rl.write('Delete this!');
// Simulate Ctrl+U to delete the line written previously
rl.write(null, { ctrl: true, name: 'u' }); 

rl.write() 方法将数据写入 readline Interfaceinput就好像它是用户提供的

rl[Symbol.asyncIterator]()#

创建一个 AsyncIterator 对象,该对象将输入流中的每一行作为字符串进行迭代。此方法允许通过 for await...of 循环异步迭代 InterfaceConstructor 对象。

输入流中的错误不会转发。

如果循环使用 breakthrowreturn 终止,则将调用 rl.close()。换句话说,迭代 InterfaceConstructor 将始终完全使用输入流。

性能与传统的 'line' 事件 API 不相符。对于性能敏感的应用程序,请使用 'line'

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

  for await (const line of rl) {
    // Each line in the readline input will be successively available here as
    // `line`.
  }
} 

readline.createInterface() 一旦被调用,将开始使用输入流。在接口创建和异步迭代之间进行异步操作可能会导致错过行。

rl.line#

节点正在处理的当前输入数据。

当从 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#

相对于 rl.line 的光标位置。

当从 TTY 流读取输入时,这将跟踪当前光标在输入字符串中的位置。光标的位置决定了在处理输入时将修改的输入字符串部分,以及终端插入符号将呈现的列。

rl.getCursorPos()#

返回光标相对于输入提示 + 字符串的实际位置。长输入(换行)字符串以及多行提示都包含在计算中。

Promises API#

稳定性:1 - 实验性

类:readlinePromises.Interface#

readlinePromises.Interface 类的实例使用 readlinePromises.createInterface() 方法构造。每个实例都与一个 input 可读 流和一个 output 可写 流相关联。output 流用于打印用户输入的提示,这些提示到达并从 input 流中读取。

rl.question(query[, options])#
  • query <string> 要写入 output 的语句或查询,在提示之前添加。
  • options <Object>
    • signal <AbortSignal> 可选地允许使用 AbortSignal 取消 question()
  • 返回值:<Promise> 一个承诺,在用户对 query 的输入响应时,该承诺将被履行。

rl.question() 方法通过将 query 写入 output 来显示它,等待用户在 input 上提供输入,然后调用 callback 函数,将提供的输入作为第一个参数传递。

调用时,rl.question() 将恢复 input 流,如果它已被暂停。

如果 readlinePromises.Interface 是使用 output 设置为 nullundefined 创建的,则不会写入 query

如果在 rl.close() 之后调用该问题,它将返回一个被拒绝的承诺。

示例用法

const answer = await rl.question('What is your favorite food? ');
console.log(`Oh, so your favorite food is ${answer}`); 

使用 AbortSignal 取消问题。

const signal = AbortSignal.timeout(10_000);

signal.addEventListener('abort', () => {
  console.log('The food question timed out');
}, { once: true });

const answer = await rl.question('What is your favorite food? ', { signal });
console.log(`Oh, so your favorite food is ${answer}`); 

类:readlinePromises.Readline#

new readlinePromises.Readline(stream[, options])#
rl.clearLine(dir)#
  • dir <integer>
    • -1:从光标左侧
    • 1:从光标右侧
    • 0:整行
  • 返回值:this

rl.clearLine() 方法将清除与 dir 标识的指定方向相关联的 stream 的当前行的操作添加到内部待处理操作列表中。调用 rl.commit() 以查看此方法的效果,除非在构造函数中传递了 autoCommit: true

rl.clearScreenDown()#
  • 返回值:this

rl.clearScreenDown() 方法将一个清除关联流中从光标当前位置到末尾内容的操作添加到内部待处理操作列表中。除非在构造函数中传递了 autoCommit: true,否则需要调用 rl.commit() 来查看此方法的效果。

rl.commit()#

rl.commit() 方法将所有待处理操作发送到关联的 stream 并清除内部待处理操作列表。

rl.cursorTo(x[, y])#

rl.cursorTo() 方法将一个将光标移动到关联 stream 中指定位置的操作添加到内部待处理操作列表中。除非在构造函数中传递了 autoCommit: true,否则需要调用 rl.commit() 来查看此方法的效果。

rl.moveCursor(dx, dy)#

rl.moveCursor() 方法将一个将光标相对于其在关联 stream 中的当前位置移动的操作添加到内部待处理操作列表中。除非在构造函数中传递了 autoCommit: true,否则需要调用 rl.commit() 来查看此方法的效果。

rl.rollback()#
  • 返回值:this

rl.rollback 方法清除内部待处理操作列表,但不将其发送到关联的 stream

readlinePromises.createInterface(options)#

  • options <Object>
    • input <stream.Readable> 要监听的 Readable 流。此选项为 必需 的。
    • output <stream.Writable> 用于写入 readline 数据的可写流。
    • completer <Function> 用于 Tab 自动完成的可选函数。
    • terminal <boolean> 如果 inputoutput 流应该被视为 TTY,并且应该向其写入 ANSI/VT100 转义码,则为 true默认值:在实例化时检查 output 流上的 isTTY
    • history <string[]> 历史记录行的初始列表。此选项仅在用户或内部 output 检查将 terminal 设置为 true 时才有意义,否则历史记录缓存机制根本不会初始化。默认值:[]
    • historySize <number> 保留的历史记录行最大数量。要禁用历史记录,请将此值设置为 0。此选项仅在用户或内部 output 检查将 terminal 设置为 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> readlinePromises 将等待一个字符的持续时间(以毫秒为单位,当读取一个模棱两可的键序列时,该键序列可以使用到目前为止读取的输入形成一个完整的键序列,也可以接受额外的输入来完成一个更长的键序列)。默认值:500
    • tabSize <整数> 一个 Tab 键等于的空格数(最小值为 1)。默认值: 8
  • 返回值:<readlinePromises.Interface>

readlinePromises.createInterface() 方法创建一个新的 readlinePromises.Interface 实例。

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

创建 readlinePromises.Interface 实例后,最常见的情况是监听 'line' 事件。

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

如果此实例的 terminaltrue,则如果 output 流定义了 output.columns 属性并在 output 上发出 'resize' 事件(当列发生变化时),则 output 流将获得最佳兼容性(process.stdout 在它是 TTY 时会自动执行此操作)。

使用 completer 函数#

completer 函数以用户输入的当前行作为参数,并返回一个包含 2 个条目的 Array

  • 一个包含匹配条目的 Array
  • 用于匹配的子字符串。

例如:[[substr1, substr2, ...], originalsubstring]

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];
} 

completer 函数也可以返回一个 <Promise>,或者异步执行。

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

回调 API#

类:readline.Interface#

readline.Interface 类的实例使用 readline.createInterface() 方法构造。每个实例都与一个 input 可读 流和一个 output 可写 流相关联。output 流用于打印用户输入的提示,这些提示到达 input 流并从 input 流读取。

rl.question(query[, options], callback)#
  • query <string> 要写入 output 的语句或查询,在提示之前添加。
  • options <Object>
    • signal <AbortSignal> 可选地允许使用 AbortController 取消 question()
  • callback <Function> 一个回调函数,在用户对 query 的输入响应时被调用。

rl.question() 方法通过将 query 写入 output 来显示它,等待用户在 input 上提供输入,然后调用 callback 函数,将提供的输入作为第一个参数传递。

调用时,rl.question() 将恢复 input 流,如果它已被暂停。

如果 readline.Interface 是使用 output 设置为 nullundefined 创建的,则不会写入 query

传递给 rl.question()callback 函数不遵循接受 Error 对象或 null 作为第一个参数的典型模式。callback 使用提供的答案作为唯一参数被调用。

如果在 rl.close() 之后调用 rl.question(),将抛出错误。

示例用法

rl.question('What is your favorite food? ', (answer) => {
  console.log(`Oh, so your favorite food is ${answer}`);
}); 

使用 AbortController 取消问题。

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

rl.question('What is your favorite food? ', { signal }, (answer) => {
  console.log(`Oh, so your favorite food is ${answer}`);
});

signal.addEventListener('abort', () => {
  console.log('The food question timed out');
}, { once: true });

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

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

  • stream <stream.Writable>
  • dir <number>
    • -1:从光标左侧
    • 1:从光标右侧
    • 0:整行
  • callback <Function> 操作完成后调用。
  • 返回值:<boolean> 如果 stream 希望调用代码等待 'drain' 事件发出后再继续写入更多数据,则为 false;否则为 true

readline.clearLine() 方法清除给定 TTY 流的当前行,方向由 dir 指定。

readline.clearScreenDown(stream[, callback])#

  • stream <stream.Writable>
  • callback <Function> 操作完成后调用。
  • 返回值:<boolean> 如果 stream 希望调用代码等待 'drain' 事件发出后再继续写入更多数据,则为 false;否则为 true

readline.clearScreenDown() 方法从光标的当前位置向下清除给定的 TTY 流。

readline.createInterface(options)#

  • options <Object>
    • input <stream.Readable> 要监听的 Readable 流。此选项为 必需 的。
    • output <stream.Writable> 用于写入 readline 数据的可写流。
    • completer <Function> 用于 Tab 自动完成的可选函数。
    • terminal <boolean> 如果 inputoutput 流应该被视为 TTY,并且应该向其写入 ANSI/VT100 转义码,则为 true默认值:在实例化时检查 output 流上的 isTTY
    • history <string[]> 历史记录行的初始列表。此选项仅在用户或内部 output 检查将 terminal 设置为 true 时才有意义,否则历史记录缓存机制根本不会初始化。默认值:[]
    • historySize <number> 保留的历史记录行最大数量。要禁用历史记录,请将此值设置为 0。此选项仅在用户或内部 output 检查将 terminal 设置为 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 <整数> 一个 Tab 键等于的空格数(最小值为 1)。默认值: 8
    • signal <AbortSignal> 允许使用 AbortSignal 关闭界面。中止信号将在内部调用界面的 close
  • 返回值:<readline.Interface>

readline.createInterface() 方法创建一个新的 readline.Interface 实例。

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

创建 readline.Interface 实例后,最常见的情况是监听 'line' 事件

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

如果此实例的 terminaltrue,则如果 output 流定义了 output.columns 属性并在 output 上发出 'resize' 事件(当列发生变化时),则 output 流将获得最佳兼容性(process.stdout 在它是 TTY 时会自动执行此操作)。

使用 stdin 作为输入创建 readline.Interface 时,程序将不会终止,直到它收到一个 EOF 字符。要退出而不等待用户输入,请调用 process.stdin.unref()

使用 completer 函数#

completer 函数以用户输入的当前行作为参数,并返回一个包含 2 个条目的 Array

  • 一个包含匹配条目的 Array
  • 用于匹配的子字符串。

例如:[[substr1, substr2, ...], originalsubstring]

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];
} 

如果 completer 函数接受两个参数,则可以异步调用它

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

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

readline.cursorTo() 方法将光标移动到给定 TTY stream 中的指定位置。

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

readline.moveCursor() 方法将光标相对于给定 TTY stream 中的当前位置移动。

readline.emitKeypressEvents(stream[, interface])#

readline.emitKeypressEvents() 方法使给定的 Readable 流开始发出与接收到的输入相对应的 'keypress' 事件。

可选地,interface 指定一个 readline.Interface 实例,当检测到复制粘贴的输入时,该实例的自动完成功能将被禁用。

如果 stream 是一个 TTY,则它必须处于原始模式。

这将由任何 readline 实例在其 input 上自动调用,如果 input 是一个终端。关闭 readline 实例不会阻止 input 发出 'keypress' 事件。

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

示例:小型 CLI#

以下示例说明了使用 readline.Interface 类来实现一个小型的命令行界面。

const readline = require('node:readline');
const rl = readline.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 循环。

const fs = require('node:fs');
const readline = require('node:readline');

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

  const rl = readline.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(); 

或者,可以使用 'line' 事件。

const fs = require('node:fs');
const readline = require('node:readline');

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

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

目前,for await...of 循环可能有点慢。如果 async / await 流和速度都很重要,可以采用混合方法。

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

TTY 键绑定#

键绑定 描述 备注
Ctrl+Shift+Backspace 删除左侧行 在 Linux、Mac 和 Windows 上无效
Ctrl+Shift+Delete 删除右侧行 在 Mac 上无效
Ctrl+C 发出 SIGINT 或关闭 readline 实例
Ctrl+H 删除左侧字符
Ctrl+D 删除右侧字符,或在当前行为空/EOF 时关闭 readline 实例 在 Windows 上无效
Ctrl+U 从当前位置删除到行首
Ctrl+K 从当前位置删除到行尾
Ctrl+Y 粘贴(恢复)之前删除的文本 仅适用于使用 Ctrl+UCtrl+K 删除的文本
Meta+Y 在之前删除的文本之间循环 仅在最后一次按键为 Ctrl+YMeta+Y 时可用
Ctrl+A 移至行首
Ctrl+E 移至行尾
Ctrl+B 后退一个字符
Ctrl+F 前进一个字符
Ctrl+L 清屏
Ctrl+N 下一个历史记录项
Ctrl+P 上一个历史记录项
Ctrl+- 撤销上一次更改 任何发出键码 0x1F 的按键都会执行此操作。在许多终端中,例如 xterm,这绑定到 Ctrl+-
Ctrl+6 重做上一次更改 许多终端没有默认的重做按键。我们选择键码 0x1E 来执行重做。在 xterm 中,它默认绑定到 Ctrl+6
Ctrl+Z 将运行中的进程移至后台。键入 fg 并按 Enter 返回。 在 Windows 上无效
Ctrl+WCtrl +Backspace 向后删除到词边界 Ctrl+Backspace 在 Linux、Mac 和 Windows 上无效
Ctrl+Delete 向前删除到词边界 在 Mac 上无效
Ctrl+Left arrowMeta+B 左移一个词 Ctrl+Left arrow 在 Mac 上无效
Ctrl+Right arrowMeta+F 右移一个词 Ctrl+Right arrow 在 Mac 上无效
Meta+DMeta +Delete 删除右侧词 Meta+Delete 在 Windows 上无效
Meta+Backspace 删除左侧词 在 Mac 上无效