EDA工具的log(日志)捕获,是一个经常会用到的功能,有助于用户查看long run job的状态和错误捕获,这里一般是利用了linux下的重定向(redirect)或者输出捕获(tee),这里通过对linux这两个命令的学习梳理,用户可以根据自身需要,优化EDA工具的LOG捕获工作。闲言少叙,ICer GO!
在Linux下,对于IO管理有三个标记,分别如下:
0:stdin
1:stdout
2:stderr
PTS的理解
可以看到,无论是0/1/2最后都会指向/dev/pts/166
这个终端号(166),可以理解,这个166终端既可以接受stdin,也可以打印stdout(如上所述)和stderr,用户在/dev/fd
目录下,可以看到类似下面的结构:
PTS是linux下的虚拟终端(pty)的一种实现方法。这里的/dev/pts/166
可以简单的理解为当前用户的具象化的虚拟终端tty。
这里表达的意思是:当前的伪终端的所有打印都会通过/dev/pts/166
这个“设备”完成,这个“设备”既可以接受stdin,也可以输出stdout和stderr。
stdin(0):
在linux下,所有的输入对被归为stdin,可以是键盘输入,也可以是文件输入,键盘输入在此不赘述。
文件输入需要借助于输入重定向<
实现
抑或利用0(stdin)结合输入重定向实现:
stdout(1):
输出重定向到指定设备
linux下的重定向符>
,可以指向固定设备,譬如这里重定向到/dev/tty
,就会带来一种类似屏幕打印的效果。
也可以指向linux的"null设备"。
输出重定向到指定文件
相较于重定向到设备,linux下的输出重定向符更多的是指向指定文件,譬如下例:
在使用重定向stdout命令的时候,如果命令的返回只有stdout,那么这个命令不会有任何返回信息,所有的信息都被重定向到指定文件中去了。
由于默认的>
的行为是对stdout的重定向,这里就近似等同于1>
,所以,一种对stdout,更为完整的重定向写法如下所示:
stderr(2):
日常的使用中,用户不可能保证每一个命令都可以正常执行,在这种情况下,命令的返回信息可能就会参杂非stdout的信息,linux将这一类归为stderr。譬如下例:
这里用户尝试ls 一个不存在的文件f4.txt。可以看到,这个时候在使用重定向输出命令的时候,终端上有了一个错误的信息输出,来表述f4.txt这个文件是不存在的。
如果这个时候查看输出重定向的消息,f1234.log。可以看到,这里只有正常的文件信息,所以,正常的重定向命令,确实只是捕获了stdout,如果用户的想实现stderr的重定向,需要使用下面的方法:
这个时候需要借用2>
来描述对于stderr信息的处理,通过上述例子,屏幕上并没有任何信息输出,这里的stdout和stderr分别被重定向到f123.log和f4.log文件里了。
类似的用户也可以只针对stderr进行重定向,譬如:
这个时候,屏幕上会把正常的stdout打印出来,stderrr信息被保留到了f4.log。
由于默认的>
的行为是对stdout的重定向,这里就近似等同于1>
,所以,一种对stdout/stderr,更为完整的重定向写法如下所示:
stdout和stderr重定向同一文件
有些情况下,用户不想将stdout和stderr分开,这样的好处是可以把命令执行的所有信息都捕捉下来(stdout+stderr),这个时候需要用到一个修饰符&
,譬如下例:
这里的重定向符号结合了修饰符,变成了&>
,所有的stdout和stderr都会被重定向到f1234.log里边了。
常言道条条大路通罗马,linux就是古谚的忠实践行者,通过命令后缀2>&1
的方式,也可以实现上述功能,具体见下:
这个方式是将stderr先重定向到stdout,然后在同一将stdout 重定向到f1234.log。
PS:对应的也可以对stdout做重定向,有兴趣的小伙伴可以试一下
重定向和屏幕捕获(tee)异同
在日常的工作中,由于EDA工具的日志都会比较长,如果简单的使用重定向,那么命令行在EDA任务完成前,屏幕都不会有任何回显,这个时候会给人一些EDA工具运行出错的误判,所以在日冲工作中,更多的工程师喜欢使用屏幕捕获(tee)这个命令:EDA工具在打印信息到屏幕上的时候,同时也会将屏显内容捕获到指定文件中:
譬如:
但是tee一样会有类似重定向的问题,就是对于stdout和stderr的分别对待,这个从tee的manual可以看到
所以说tee只能捕获屏幕上的stdout信息,而不能去捕获stderr的信息,虽然stdout和stderr都会出现在屏幕上,譬如下例:
但是对于EDA用户,这个是不方便的,用户总是期望捕获命令的所有输出。结合上述讲解,也可以借助修饰符&
让tee完成这个任务:
- 方法一:使用命令|&
进行捕获,譬如下例:
方法二:对stderr进行重定向后处理后的,而后用tee对stdout进行捕获
shell的异同
由于bash是linux默认的shell,这里对stdin/stdout/stderr(0/1/2)支持的很好,所以上述命令都可以正常使用,但是对于csh/tcsh这类基于C的shell,确实不能直接使用0/1/2进行处理的
从上例可以看到,2这个在bash里边标记stderr的标记字,在tcsh下是被当作argument来处理的。但是tcsh的作者还是尊重原著的,使用修饰符&
,就可以让命令在bash/tcsh下实现兼容:
所以,对于shell之间,唯一的区别就是tcsh下无法将stdout和stderr分别处理,只能做合并,或者只捕获stdout。
EDA工具日志捕获实践
经过上边的描述,用户对于linux下的重定向和tee有了全面的认识,对于大部分日常的EDA工具,用户使用常规对stdout处理的命令就可以了,但是对于S家的StarRC工具,这个可能有一点需要特殊处理,
用户尝试对StarXtract 命令的输出进行常规输出重定向,但是这个时候尽管使用了>
,但是屏幕上依然有输出
这个时候,再看重定向的目标文件,发现字节数竟然是0。
所以可以判定,StarXtract 这个命令的输出都被判定为stderr。
方法一:重定向捕获:用户需要使用2>
重定向StarXtract 命令输出:
方法二:tee捕获:用户需要使用|&
重定向StarXtract 命令输出:
【敲黑板划重点】
重定向是linux基础的IO操作方式,都可以轻松使用0/1/2(bash下)进行控制,但是对于tee这个屏幕捕获的命令,是针对stdout的捕获,和重定向相比,用户只能选择把steout或者stdout和stderr统一捕获到同一文件中,不能分开捕获,这个也是符合tee的设计初衷的。
对于所有的EDA工具的屏幕输出,对于常见的shell(bash/tcsh/csh)用户可以一劳永逸的是用 “|&”的方式对stdout和stderr将屏幕输出全部捕获出来
cmd |& tee cmd.log
参考资料
刘忆智(清华大学出版社出版) Linux从入门到精通