【转】从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 ...
随机推荐
- 'adb remount'的作用是什么?在什么情况下有用?
'adb remount' 将 '/system' 部分置于可写入的模式,默认情况下 '/system' 部分是只读模式的.这个命令只适用于已被 root 的设备. 在将文件 push 到 '/sys ...
- LeetCode题解之Rotate String
1.题目描述 2.问题分析 直接旋转字符串A,然后做比较即可. 3.代码 bool rotateString(string A, string B) { if( A.size() != B.size( ...
- Python tuple
元组其实跟列表差不多,也是存一组数,只不是它一旦创建,便不能再修改,所以又叫只读列表 语法 names = (a,b,c) 它只有2个方法,一个是count,一个是index. 当然也有可变元祖: 可 ...
- for之于while的优势
前言 for与while各有功效,下面就只列举for之于while的优势有哪些 优势 1.循环中提供了特殊的机会来将变量的作用域最小化.(无论是传统的还是for-each形式的)for循环,都允许声明 ...
- SQLServer导数据到Oracle
从SQLServer导数据到Oracle大概有以下几种方法: 使用SSMS的导出数据向导,使用Microsoft ODBC for Oracle或Oracle Provider for OLE DB连 ...
- JavaScript原型链基础(prototype chain)
1.函数基础 2.对象基础 3.原型链基础
- C++第六次作业
前言 拿到作业的时候,整个人都不好了,虽然之前和同学说以后一起写游戏,画界面,然而现在的自己对界面的知识一窍不通,虽然同学分享了一些资料,但是通过这次作业,发现自己火候还是不够-- 问题描述及仓库地址 ...
- JavaSript模块规范 - AMD规范与CMD规范介绍[转]
原文地址:http://blog.chinaunix.net/uid-26672038-id-4112229.html JavaSript模块化 在了解AMD,CMD规范前,还是需要先来简单地了解下什 ...
- 单一事件中心管理组件通信( vuex )
有时候两个组件也需要通信(非父子关系).在简单的场景下,可以使用一个空的 Vue 实例作为中央事件总线: 补充$emit ,$on的讲解 代码: <!DOCTYPE html> <h ...
- python创建目录保存文件
创建目录 在Python中可以使用os.mkdir()函数创建目录(创建一级目录). 其原型如下所示: os.mkdir(path) 其参数path 为要创建目录的路径. 例如要在D盘下创建hello ...