js 实现终端
使用 Node.js 实现终端功能
Node.js 提供了 readline 模块和 process 标准输入输出流,可以轻松实现终端交互功能。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('请输入命令: ', (command) => {
console.log(`执行命令: ${command}`);
rl.close();
});
添加命令历史记录
通过维护一个数组来存储命令历史,并实现上下箭头浏览历史功能。
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const history = [];
let historyIndex = -1;
rl.on('line', (input) => {
history.push(input);
console.log(`执行: ${input}`);
});
process.stdin.on('keypress', (str, key) => {
if (key.name === 'up' && historyIndex < history.length - 1) {
historyIndex++;
rl.write(null, {ctrl: true, name: 'u'});
rl.write(history[history.length - 1 - historyIndex]);
}
if (key.name === 'down' && historyIndex > 0) {
historyIndex--;
rl.write(null, {ctrl: true, name: 'u'});
rl.write(history[history.length - 1 - historyIndex]);
}
});
实现自动补全功能
利用 readline 的 completer 选项可以添加命令自动补全功能。
const commands = ['help', 'exit', 'clear', 'list'];
const completer = (line) => {
const hits = commands.filter(c => c.startsWith(line));
return [hits.length ? hits : commands, line];
};
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
completer
});
添加彩色输出
使用 chalk 库可以为终端输出添加颜色。
const chalk = require('chalk');
console.log(chalk.blue('蓝色信息'));
console.log(chalk.red.bold('红色加粗错误'));
console.log(chalk.green('成功信息'));
实现多行输入
通过检测特定字符(如分号)来判断命令是否结束。
let buffer = '';
rl.on('line', (input) => {
buffer += input;
if (input.endsWith(';')) {
console.log(`执行多行命令: ${buffer}`);
buffer = '';
} else {
console.log('继续输入...');
}
});
创建自定义提示符
可以动态修改提示符来显示当前工作目录或其他信息。
function setPrompt() {
rl.setPrompt(`[${process.cwd()}] $ `);
rl.prompt();
}
rl.on('line', (input) => {
if (input === 'cd') {
// 改变目录逻辑
setPrompt();
}
});
setPrompt();
处理 SIGINT 信号
优雅地处理 Ctrl+C 中断信号。
rl.on('SIGINT', () => {
rl.question('确定要退出吗? (y/n) ', (answer) => {
if (answer.match(/^y(es)?$/i)) rl.close();
else rl.prompt();
});
});
实现命令路由
建立一个命令路由系统来处理不同命令。
const commands = {
help: () => console.log('可用命令: help, exit'),
exit: () => process.exit(0),
greet: (args) => console.log(`Hello, ${args[0] || 'stranger'}!`)
};
rl.on('line', (input) => {
const [cmd, ...args] = input.trim().split(/\s+/);
if (commands[cmd]) commands[cmd](args);
else console.log(`未知命令: ${cmd}`);
});
添加异步命令支持
处理需要异步操作的命令。
const commands = {
fetch: async (url) => {
const response = await fetch(url[0]);
console.log(await response.text());
}
};
rl.on('line', async (input) => {
const [cmd, ...args] = input.trim().split(/\s+/);
if (commands[cmd]) await commands[cmd](args);
});






