【转】从Shell脚本内部将所有标准输出及标准错误显示在屏幕并同时写入文件的方法
如果全部都要重定向的话每一条命令后面>>并不方便,可以这么做。
在开头就声明
exec 1>>$log_file
表示将脚本中所有的正确输出全部追加到$log_file,错误信息会输出到stdout。
如果想把错误信息也输出到$log_file,那么只需要补一句
exec 2 >> $log_file
就可以了
利用script命令记录下会话过程
在Unix系统维护中,有时候系统工程师希望能够记录下会话的过程。如在测试一个系统功能的时候,工程师就希望将测试的步骤都一一的纪录下来。以便出现问 题时利用这份资料进行追踪分析。如有时候在制作培训文档的时候,可能也需要这些会话记录,以方便培训师制作PPT等培训文档。总之就是一句话,系统工程师 现在想要记录某个会话的过程,在Unix系统中能否实现? 首先当系统工程师想要记录某个会话的时候,则只需要在会话开始时输入script命令。输入这个命令后,系统就会将当前用户的所有键盘操作、屏幕输出以及 错误信息等等保存到一个特定的文件中。如上面执行了ps命令与who命令后,希望就会将这两个命令(用户的键盘操作)、屏幕输出(命令的执行结果)等等保 存到文件中。当工程师需要退出记录过程时,则只需要输入exit命令,系统就会就是script done的提示信息。表示系统已经结束了记录工作。 三、将正确信息与错误信息都保存在同一个文件中。
除了可以将正确信息与错误信息保存在不同的文件中,还可以将它们合并在同一个文件中。要实现这个需求,可以采取两种途径。
一是通过文件合并来实现。即先将错误信息与正确信息保存在两个不同的文件中。然后再需要的时候,来利用文件合并的功能将他们合并在同一个文件中。如利 用cat命令加上>>重定向符号就可以将两个文件合并在一起了。注意这里用的是>>符号而不是>符号。这个命令很容易理 解,就是先将某个文件中(如保存错误信息的文件)的内容读出来,然后再通过重定向符号>>(这个符号的含义是追加,而不是替换)将读出来的错 误信息追加到另外一个文件中(如保存正确信息的文件)。通过这个方式就可以两正确信息与错误信息合并保存在同一文件中。
1、管道符的" | "的作用只是把前一个程序的标准输出流(stdout)的数据 作为后一个程序 的标准输入流stdin的数据,如不进行重定向,则其他输出流的信息是无法传给后面的程序的
2、屏幕得到的信息不一定是从程序的标准输出来的,也包括标准错误输出流stderr中的信息
3、有些程序(特别是象bash 、make这样执行了其他程序的程序)的设计者为了省事,把一些正常情况的信息也放在stderr中输出(即使程序本身并无错误),而stdout用来输 出被调用程序的执行时信息,造成了用户的误解 简单编写了一下脚本,通过ssh登陆在命令行下运行正常,可是将脚本添加到crontab中就不正常。想记录一下输出信息,分析一下错误原因。 将脚本通过使用 > info.log 重定向输出,结果发现一些在命令行下可以看到的文本信息没有记录到 info.log 文件中,研究了一下,那些输出估计是输出到了标准错误上。
研究了一下通常添加命令后面几个输出含义
■>/dev/null 输出到空设备,表示丢掉输出信息。
■2 > &1 将输出到标准错误的信息输出到标准输出设备(通常是屏幕) 有3个默认的i/o,
■0 是标准输入,一般是键盘
■1 是标准输出,一般是屏幕了
■2 是标准错误,有时候屏幕上可以看到,但是重定向的文件中看不到的就是它了
在编写稍微复杂的Shell脚本时,我们常常需要将标准输出和标准错误信息记录下来,以往我们通过如下形式办到:
somescript.sh > log 2>&1
但这对规范的shell是不太完美的,一是log文件的位置及名称,只能由着执行者来定,存在不确定性;二是执行者是否记得使用这样的句式来确保操作显示 有记录,也无法保证
所以,我们需要在shell脚本内部指定,不受执行者影响而记录下显示输出的手段,而且,我们还不能用愚蠢的每句后面来一个| tee $logfile的方式
以下为实现方法,以Korn Shell为准:
变量: logfile - 所有信息输出的文件
fifofile - 为同时输出到屏幕和文件所建立的管道文件
Shell内部可以支持的重定向标准输出和标准错误设备的基本方法: exec 1>$logfile exec 2>&1
但是,这样就只能将所有信息输出到$logfile,无法实现同时显示在屏幕的目的。
不可能有exec 1>|tee $logfile的用法
以往,在命令行将错误输出也导向屏幕及文件的方法是: somescript.sh 2>&1 | tee $logfile 这里用到管道,而exec命令并不支持管道用法,所以我们需要建立fifo文件来完成
但是,fifo管道文件是阻塞形管道,没有随时将其内容输出的话,脚本将hang住无法继续,所以我们要用“cat 管道文件”的方式将其随时导出,为了不影响后续命令执行,cat这一句必须放到后台。因为cat管道文件内容的时候,永远不会结束,因为不会遇到EOF标 记(就是控制字符Ctrl-D),除非在管道中出现了Ctrl-D,所以我们在脚本最后需要显示一个Ctrl-D,比较方便的方法是print "\015"(015是8进制,换算成10进制就是13,即Ctrl-D的ASCII码) 最后写法:
test.sh
logfile=test.log
fifofile=test.fifo
mkfifo $fifofile
cat $fifofile | tee $logfile & exec 1>$fifofile exec 2>&1
# some commands to produce normal and error output cal badcommand to generate stderr messages
# print "\015"
复制代码 运行结果:
[root@system:/tt] sh test.sh October 2008 Sun Mon Tue Wed Thu Fri Sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 test.sh[12]: badcommand: not found.
[root@system:/tt] cat test.log October 2008 Sun Mon Tue Wed Thu Fri Sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 test.sh[12]: badcommand: not found. [root@system:/tt]
【转】从Shell脚本内部将所有标准输出及标准错误显示在屏幕并同时写入文件的方法的更多相关文章
- Shell标准输出、标准错误
shell中可能经常能看到:>/dev/null 2>&1 eg:sudo kill -9 ps -elf |grep -v grep|grep $1|awk '{print $4 ...
- Shell标准输出、标准错误 >/dev/null 2>&1
Shell中可能经常能看到:>/dev/null 2>&1 eg:sudo kill -9 `ps -elf |grep -v grep|grep $1|awk '{print ...
- sort命令与cat区别25.1 由于sort默认是把结果输出到标准输出,所以需要用重定向才能将结果写入文件,形如sort filename > newfile [root@shiyan a]# cat a.txt aaaaaa [root@shiyan a]# sort a.txt >c.txt ------------- 在重定向前会自动创建c.txt这个文件。 [root@shiyan
25.1 由于sort默认是把结果按照行排序后输出到标准输出,所以需要用重定向才能将结果写入文件,形如sort filename > newfile[root@shiyan a]# cat a. ...
- java 标准输出与标准错误 out与 err 区别 用法 联系 java中的out与err区别 System.out和System.err的区别 System.out.println和System.err.println的区别 Java重定向System.out和System.err
本文关键词: java 标准输出与标准错误 out与 err 区别 用法 联系 java中的out与err区别 System.out和System.err的区别 System.out.pri ...
- linux将标准输出和标准错误输出都重定向到一个文件?
需求描述: 今天在写crontab,里面有标准输出和错误输出,之前使用的是 > /dev/null 2>&1 那这个意思也就等同于将标准输出和错误输出都输出到/dev/null中, ...
- 文件IO详解(四)---标准输入、标准输出和标准错误
每个进程都会默认打开3个文件描述符,即0.1.2.其中0代表标准输入流.1代表标准输出流.2代表标准错误流.通常标准输入流对应着键盘的设备文件.标准输出流和错误流对应着显示器的设备文件.在编程中通常使 ...
- 7、pytest -- 捕获标准输出和标准错误输出
目录 1. 标准输出/标准错误输出/标准输入的默认捕获行为 2. 修改和去使能捕获行为 2.1. 文件描述符级别的捕获行为(默认) 2.2. sys级别的捕获行为 2.3. 去使能捕获行为 3. 使用 ...
- Pytest权威教程09-捕获标准输出及标准错误输出
目录 捕获标准输出及标准错误输出 默认 stdout/stderr/stdin 捕获行为 设置捕获方法或禁用捕获 调试中使用print语句 在测试用例中使用的捕获的输出 返回: Pytest权威教程 ...
- Bash基础——Shell脚本内部常用环境变量
$@和$*区别 不加引号的时候没区别 #! /usr/bin/bash function print_args_at { printf "%s\n" $@ echo $@ } fu ...
随机推荐
- python终端总是无法删除字符
yum install readline-devel
- Python tuple
元组其实跟列表差不多,也是存一组数,只不是它一旦创建,便不能再修改,所以又叫只读列表 语法 names = (a,b,c) 它只有2个方法,一个是count,一个是index. 当然也有可变元祖: 可 ...
- SQL Server中的高可用性(3)----复制 (转载)
在本系列文章的前两篇对高可用性的意义和单实例下的高可用性做了阐述.但是当随着数据量的增长,以及对RTO和RPO要求的严格,单实例已经无法满足HA/DR方面的要求,因此需要做多实例的高可用性.本文着重对 ...
- JavaScript获取请求参数
<script type="text/javascript"> //获取请求参数 function paramsMap() { var url = window.loc ...
- mybatis 中的<![CDATA[ ]]>
在使用mybatis 时我们sql是写在xml 映射文件中,如果写的sql中有一些特殊的字符的话,在解析xml文件的时候会被转义,但我们不希望他被转义,所以我们要使用<![CDATA[ ]]&g ...
- Eclipse中Tomcat的配置
1.Window-Preferences-Server-Runtime Environments 2.点击Add,选择相应的Tomcat版本,我的是7.0的所以我选择这个.并勾选Create a ne ...
- Linux运维之shell脚本基础知识
1.bash中的算术运算 let运算符 [root@:vg_adn_tidbCkhsTest ~/tidb-bench/sysbench]#echo $i [root@:vg_adn_tidbCkhs ...
- 026.6 网络编程 tomcat
###############Tomcat中相关文件作用 bin:启动关闭服务器的脚本 Conf:配置文件 Lib:Tomcat的jar包,只要部署项目到Tomcat,所有项目可共用 ...
- ajax知识点及正则表达式总结
一.JSON JSON是JavaScript Object Notation 的首字母缩写,单词的意思是javascript对象表示法,这里说的json指的是类似于javascript对象的一种数 ...
- BZOJ2095:[POI2010]Bridges(最大流,欧拉图)
Description YYD为了减肥,他来到了瘦海,这是一个巨大的海,海中有n个小岛,小岛之间有m座桥连接,两个小岛之间不会有两座桥,并且从一个小岛可以到另外任意一个小岛.现在YYD想骑单车从小岛1 ...