Node.js 控制台

什么是终端

在过去,一个机构可能只有一台主机,职员使用电传打印机(Teletypewritter 又简称为tty)通过串口连接到主机。后来人们又在电传打印机的基础上进行了改进,程序的输出不再是打印到纸带上而是显示屏上,并且支持彩色显示,这样的设备被称为终端(Terminal)。一台主机可以有很多个终端,早期的主机只支持串口线的终端,对应的设备叫做串口终端(Serials Terminal),又发展出了伪终端,以便于支持GUI,后来串口终端渐渐被图形界面的伪终端取代,也就是我们今天所说的终端。

但是在主机的系统启动完成之前,终端是不能连接到主机上的。为了能记录出主机开机过程的日志,也便于在主机出故障无法启动操作系统时进行检修维护,又多了一个叫做控制台的设备。一台主机有且只能有一个控制台。文件主机的重要日志,比如开机关机的日志和记录,重要应用程序的日志,都会输出到控制台来。 

与Node.js终端相关的模块有STDIO、TTY、REPL。

STDIO

打印到stdout和stderr。与大多数Web浏览器的控制台对象提供的功能类似,这里将输出发送到stdout或stderr。

TTY

在Linux中,TTY也许是跟终端有关系的最为混乱的术语。TTY是TeleTYpe的一个老缩写。Teletypes,或者teletypewriters,原来指的是电传打字机,是通过串行线用打印机键盘通过阅读和发送信息的设备,和古老的电报机区别并不是很大。之后,当计算机只能以批处理方式运行时(当时穿孔卡片阅读器是唯一一种使程序载入运行的方式),电传打字机成为唯一能够被使用的“实时”输入/输出设备。最终,电传打字机被键盘和显示器终端所取代,但在终端或TTY接插的地方,操作系统仍然需要一个程序来监视串行端口。一个getty“Get TTY”的处理过程是:一个程序监视物理的TTY/终端接口。对一个虚拟网络服务器(VNC)来说,一个伪装的TTY(Pseudo-TTY,即假冒的TTY,也叫做“PTY”)是等价的终端。当你运行一个xterm(终端仿真程序)或GNOME终端程序时,PTY对虚拟的用户或者如xterm一样的伪终端来说,就像是一个TTY在运行。“Pseudo”的意思是“duplicating in a fake way”(用伪造的方法复制),它相比“virtual”或“emulated”更能真实的说明问题。而在现在的计算中,它却处于被放弃的阶段。

REPL

交互式解释器(REPL)既可以作为一个独立的程序运行,也可以很容易地包含在其他程序中作为整体程序的一部分使用。REPL为运行JavaScript脚本与查看运行结果提供了一种交互方式,通常REPL交互方式可以用于调试、测试以及试验某种想法。

在终端输入 node 命令,会出现个 > 箭头,可以输入javascript代码进行调试。

例如:

console.log('hello world');  // 回车
打印出 hello world

STDIO - 标准输入输出到控制台(console)

console.log([data],[...])

换行打印到基本输入。

第一个参数是一个字符串,其中包含零个或多个占位符。每一个占位符被替换其相应的参数。如果占位符没有相应的参数,将占位符不会被替换,而是直接打印出占位符的字面量。

支持的占位符:

god   %s - 字符串。good

book   %d - 数字(包括整数和浮点数)。this

this   %j - JSON。sex

测试1,只有第一个参数的情况。
 console.log("hello world"); // 在终端会打印出 hello world
测试2,具有占位符,但后面无对应参数。
 console.log("hello %s");   // 打印出 hello %s
测试3,具有占位符,后面对应相关参数。
 console.log("hello %s","world!!"); // 打印出 hello world!!
 console.log("1+1 = %d",2);    // 打印出 1+1 = 2
 console.log("a json object : %j",{bookAuthor:"brighthas"}); // 打印出 a json object : {"bookAuthor":"brighthas"}

 注意:这里打印的是 "bookAuthor" 而不是 bookAuthor,
 如果直接用 console.log({bookAuthor:"brighthas"})打印 bookAuthor就不会出现双引号。
测试4,多个参数。
 console.log("aa","bb","cc");   // 打印出 aa bb cc , 之间有一个空格。
 console.log("aa %d%s",121,"bbb")    //  打印出 aa 121bbb 
 console.log("aa %d%s","ccc","bbb")  //  打印出 aa NaNbbb  我们会看到 ccc 参数被转换为NaN,
                                     //  说明内部会根据占位符类型转换相应的参数。

console.info([data], [...])

与console.log使用方法相同。

console.error([data], [...])

与console.log使用方法相同,不过,打印到stderr。

console.warn([data], [...])

与console.log使用方法相同,不过,打印到stderr。

console.dir(object)

打印出该对象的所有属性和属性值。

console.time(label)

标记时间,与console.timeEnd 搭配使用。

console.timeEnd(label)

完成计时器,打印出从console.time标记开始,到执行console.timeEnd之间的执行时间。

测试1
 console.time("test");
 for (var i = 0; i < 100; i++) {
   var o = new Object();
 }
 console.timeEnd("test");
 //打印出 test : 5ms 
 //这个时间不是固定的,根据计算机性能而定。

console.trace(label)

打印当前位置的堆栈信息到标准错误stderr输出。可以追踪函数的调用轨迹。

测试1
 console.trace("test");

会打印出如下类似的信息:

Trace: test
  at repl:1:10
  at REPLServer.self.eval (repl.js:110:21)
  at Interface.(repl.js:239:12)
  at Interface.EventEmitter.emit (events.js:95:17)
  at Interface._onLine (readline.js:202:10)
  ......

console.assert(expression, [message])

如果expression等于false,就会抛出消息为[message]的AssertionError异常。

测试1
console.assert(false,"test error");
// 打印结果:
AssertionError: test error
  at Console.assert (console.js:102:23)
  at repl:1:10
  at REPLServer.self.eval (repl.js:110:21)
  at Interface.(repl.js:239:12)
  ......