如何在控制台的多行中更新数据

How to update data on multiple lines of console

本文关键字:更新 数据 控制台      更新时间:2023-09-26

我想在控制台的两行中显示数据。我只想每次都更新这两行。

到目前为止我所做的是-

var _logInline = function(alpha, bravo) {
    process.stdout.cursorTo(0, 0);
    process.stdout.clearLine();
    process.stdout.cursorTo(0);
    process.stdout.write(alpha.toString());
    process.stdout.write(''n');
    process.stdout.clearLine();
    process.stdout.cursorTo(0);
    process.stdout.write(bravo.toString());
    process.stdout.write(''n');
};
var delay = 1000;
var time = 0;
setInterval(function() {
    time++;
    _logInline('alpha-' + time, 'bravo-' + time * time);
}, delay);

这个解决方案的明显问题是光标会移到窗口的顶部。我不希望这样,相反,它应该在光标当前所在的位置显示内容。可能我需要先在逻辑中获取当前光标的位置。有办法做到这一点吗?

另一种也是最优选的解决方案是获得一个可以做同样事情的库

编辑:我在stackoverflow上看到了一些问题,这些问题提供了在没有新行的情况下进行日志记录的选项,但这并不是我想要的。我想要多个无新行日志记录。

ncurses是我用来控制终端的最强大的库,mscdex有一个优秀的npm包,可以绑定到c库https://npmjs.org/package/ncurses

但对于您的需求来说,这可能有点过头了,这里有一个替代解决方案,但它涉及到使用bash脚本:

基于这一要点,我将以下代码改编为适合您的示例,你可以从gist下载或在这里阅读,别忘了用给exec访问bash脚本的权限

  chmod +x cursor-position.sh 

光标位置.js

module.exports = function(callback) {
  require('child_process').exec('./cursor-position.sh', function(error, stdout, stderr){
    callback(error, JSON.parse(stdout));
  });
}

光标位置.sh

#!/bin/bash
# based on a script from http://invisible-island.net/xterm/xterm.faq.html
# http://stackoverflow.com/questions/2575037/how-to-get-the-cursor-position-in-bash
exec < /dev/tty
oldstty=$(stty -g)
stty raw -echo min 0
# on my system, the following line can be replaced by the line below it
echo -en "'033[6n" > /dev/tty
# tput u7 > /dev/tty    # when TERM=xterm (and relatives)
IFS=';' read -r -d R -a pos
stty $oldstty
# change from one-based to zero based so they work with: tput cup $row $col
row=$((${pos[0]:2} - 1))    # strip off the esc-[
col=$((${pos[1]} - 1))
echo '{'"row'":$row,'"column'":$col'}

index.js

var getCursorPosition = require('./cursor-position');
var _logInline = function(row, msg) {
  if(row >= 0) row --; //litle correction
  process.stdout.cursorTo(0, row);
  process.stdout.clearLine();
  process.stdout.cursorTo(0, row);
  process.stdout.write(msg.toString());
};
var delay = 1000;
var time = 0;
//Start by getting the current position
getCursorPosition(function(error, init) {
  setInterval(function() {
      time++;
      _logInline(init.row, 'alpha-' + time);
      _logInline(init.row + 1, 'bravo-' + time * time);
  }, delay);
});

我考虑了很长一段时间。。。

这里有一个非常天真的多行解决方案:


import {execSync} from "child_process";
var util = require('util');
var x = 0;
var y = 100;
setInterval(function () {
    execSync('tput cuu1 tput el tput cuu1 tput el', {stdio: 'inherit'});
    process.stdout.write(`hello1: ${x++}'nhello2: ${y++}'r`);  // needs return '/r'
    // util.print('hello: ' + x + ''r');  // could use this too
}, 1000);

我会更新什么时候我会有一个更强大的实现。