《Linux命令行与shell脚本编程大全》 第十四章 学习笔记
第十四章:呈现数据
理解输入与输出
标准文件描述符
| 文件描述符 | 缩写 | 描述 |
| 0 | STDIN | 标准输入 |
| 1 | STDOUT | 标准输出 |
| 2 | STDERR | 标准错误 |
1.STDIN
代表标准输入。对于终端界面来说,标准输入是键盘
使用输入重定向符号(<)时,Linux会用重定向指定的文件来替换标准输入文件描述符
2.STDOUT
代表标准输出。对于终端界面来说,标准输出是屏幕
3.STDERR
代表标准错误输出。默认情况下,STDOUT文件描述符和STDERR文件描述符指向同样的地方,即显示器。
重定向STDOUT并不会自动重定向STDERR
重定向错误 & 重定向错误和错误数据
在使用重定向符号时定义STDERR文件描述符就可以重定向错误输出。
$ ls none 2> err_log
重定向错误和正常输出,需要用两个重定向符号
ls 3152.pdf none 1> temp1 2> temp2
注意:不能使用这种方法将他们重定向到同一个文件中,一个重定向会覆盖另一个,所以不会正常工作。
想要将其重定向到同一个文件,可以使用重定向符号“&>”(只能在bash中使用)
ls 3152.pdf none &> temp
关于重定向更详尽的讲解请参看(#1)
在脚本中重定向输出
临时重定向
echo "error message" >&2
在重定向符号后面加上and符号以及文件描述符即可
这样就将上面的log输出到标准错误中(当然,还是黑字不是红字)
永久重定向
用exec命令告诉shell脚本执行期间重定向某个文件描述符
#!/bin/bash
exec 1>ok
exec 2>err echo "this is right"
echo "this is wrong" >&2
注意:上面即使把STDOUT重定向了,依然可以将echo重定向到STDERR
在脚本中重定向输入
exec 0< testfile
创建自己的重定向
创建输出文件描述符
exec 3>mylog
echo "this is my log" >&3
同上面一模一样,只是文件描述符换成了3-8
重定向文件描述符
将已经重定向的文件描述符恢复:
比如我们要恢复标准输出,基本的思路就是,使用一个文件描述符定向到标准输出,然后再把标准输出定向到其他地方,比如文件。当想把标准输出重定向回来的时候,只需将他重定向到之前使用的文件描述符那里即可。
#!/bin/bash
exec 3>&1
exec 1>temp_log
echo "you can't see me!"
exec 1>&3
echo "Now, you can see me."
创建输入文件描述符
与上面方法完全一致
exec 4<&0
exec 0<file1
exec 0<&4
创建读写文件描述符
在向同一个文件中进行读取数据、写入数据操作时,shell会维护一个内部指针,指明现在指向什么位置。
任何读或写都会从文件指针上次保存的位置开始。
#!/bin/bash exec 3<> test.txt
read line <&3
echo "$line"
echo "This a new line." >&3
其中的test.txt为
$ cat test.txt
This is the first line.
This is the second line.
This the third line.
执行上面的脚本,虽然控制台输出显得一切正常,但是并不会在test.txt末尾加一行
因为之前读取了第一行,所以输入的时候会输入到第二行,把之前第二行的内容覆盖掉,显得结果变得有些诡异
$ cat test.txt
This is the first line.
This a new line.
d line.
This the third line.
关闭文件描述符
如果你创建了新的输入或输出文件描述符,shell会在脚本退出时自动关闭他们。
手动关闭文件描述符,则要将其重定向到特殊符号&-
当关闭了文件描述符之后,如果再使用它,就会报错。
#!/bin/bash
exec 3> test.txt
echo "This a new line." >&3
exec 3>&-
echo "This another line." >&3
执行后结果:
$ file_descriptor_test
./file_descriptor_test: line 5: 3: Bad file descriptor
如果之后在脚本中打开了同一个输出文件,文件原有内容会被覆盖。
列出打开的文件描述符
可以使用lsof命令。如果普通用户要用lsof命令,那么需要使用全路径。
-a:对其他两个选项结果执行布尔AND运算
-p:指定进程($$指当前进程)
-d:指定文件描述符几个
$ lsof -a -p $$ -d 0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 1929 su1216 0u CHR 136,0 0t0 3 /dev/pts/0
bash 1929 su1216 1u CHR 136,0 0t0 3 /dev/pts/0
bash 1929 su1216 2u CHR 136,0 0t0 3 /dev/pts/0
相应的列含义为:
| 列 | 描述 |
| COMMAND | 正在运行的命令名的前9个字符 |
| PID | 进程的PID |
| USER | 进程属主的登录名 |
| FD | 文件描述符数目以及访问类型(r=读,w=写,u=读写) |
| TYPE | 文件的类型(CHR=字符型,BLK=块型,DIR=目录,REG=常规文件) |
| DEVICE | 设备的设备号(主设备号和从设备号) |
| SIZE | 文件大小(如果有的话) |
| NODE | 本地文件的节点数 |
| NAME | 文件名 |
与STDIN、STDOUT和STDERR关联的文件类型是字符型。因为STDIN、STDOUT和STDERR文件描述符都指向终端,所以输出文件的名称就是终端的设备名。所有3种标准文件都支持读和写。
#!/bin/bash
exec 3> test.txt
exec 4< test.txt
exec 5<> test.txt /usr/bin/lsof -a -p $$ -d 0,1,2,3,4,5
下面为输出结果:
$ file_descriptor_test
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
file_desc 13421 su1216 0u CHR 136,1 0t0 4 /dev/pts/1
file_desc 13421 su1216 1u CHR 136,1 0t0 4 /dev/pts/1
file_desc 13421 su1216 2u CHR 136,1 0t0 4 /dev/pts/1
file_desc 13421 su1216 3w REG 8,7 0 3039280 /home/su1216/android/source/linux_learned/test.txt
file_desc 13421 su1216 4r REG 8,7 0 3039280 /home/su1216/android/source/linux_learned/test.txt
file_desc 13421 su1216 5u REG 8,7 0 3039280 /home/su1216/android/source/linux_learned/test.txt
阻止命令输出
可以将输出发送给位桶(/dev/null),发给到它的任何东西都会消失
关于位桶更多内容参见(#1)
创建临时文件
Linux使用/tmp目录作为临时目录,当系统启动时,Linux会自动删除目录下所有文件
系统上任何账户都有权限在/tmp中读写。
mktemp命令可以在/tmp中创建一个唯一的临时文件,不使用默认的umask值。文件的读写权限将会分配给文件的属主,并将你设置为文件的属主,其他人无法访问,root除外。
创建本地临时文件
默认情况下,mktemp会在本地目录中创建临时文件
mktemp tmp.XXXXXXXXXX
至少为3个X
$ mktemp abc.XX
mktemp: too few X's in template `abc.XX'
$ mktemp abc.XXX
abc.84E
输出即为新建立的文件名,这样就可以引用此文件
创建多个临时文件,mktemp会保证文件的唯一性
在/tmp目录下创建临时文件
mktemp -t tmp.XXXXXXXXXX
使用-t选项即可
$ mktemp -t abc.XXX
/tmp/abc.z20
输出为临时文件的全路径
创建临时目录
mktemp -d tmp.XXXXXXXXXX
使用-d选项即可
记录消息
tee命令相当于管道的T型接头,它将从STDIN过来的数据同时发给两个目的地,一个是STDOUT,另一个是tee命令所指定。
$ date | tee test.txt
2013年 08月 21日 星期三 21:12:28 CST
$ cat test.txt
2013年 08月 21日 星期三 21:12:28 CST
tee默认会覆盖指定文件中的内容,如果想追加,那么要使用-a选项
转贴请保留以下链接
本人blog地址
《Linux命令行与shell脚本编程大全》 第十四章 学习笔记的更多相关文章
- 《Linux命令行与shell脚本编程大全》 第二十七章 学习笔记
第二十七章:shell脚本编程进阶 监测系统统计数据 系统快照报告 1.运行时间 uptime命令会提供以下基本信息: 当前时间 系统运行的天数,小时数,分钟数 当前登录到系统的用户数 1分钟,5分钟 ...
- 《Linux命令行与shell脚本编程大全》 第二十三章 学习笔记
第二十三章:使用数据库 MySQL数据库 MySQL客户端界面 mysql命令行参数 参数 描述 -A 禁用自动重新生成哈希表 -b 禁用 出错后的beep声 -B 不使用历史文件 -C 压缩客户端和 ...
- 《Linux命令行与shell脚本编程大全》 第三章 学习笔记
第三章:基本的bash shell命令 bash程序使用命令行参数来修改所启动shell的类型 参数 描述 -c string 从string中读取命令并处理他们 -r 启动限制性shell,限制用户 ...
- 《Linux命令行与shell脚本编程大全》 第四章
4.1 监测程序 1. ps 默认只显示运行在当前控制台下的属于当前用户的进程. 可以接很多选项,比如 -A表示所有进程 -e等. 2. ps -l 查看进程更多信息 UID:启动这些进程的用 ...
- 《Linux命令行与shell脚本编程大全》 第六章环境变量
很多程序和脚本都通过环境变量来获取系统信息.存储临时数据和配置信息. 6.1 什么是环境变量: bash shell用一个叫环境变量(environment variable)的特性来存储有关shel ...
- 《Linux命令行与shell脚本编程大全》第十三章 更多的结构化命令
本章讨论bash shell的循环命令for.while和until 13.1 for命令 重复执行一系列命令在编程中很常见. bash shell提供了for命令,允许你创建一个遍历一系列值的循环. ...
- 《Linux命令行与shell脚本编程大全》第二十一章 sed进阶
本章介绍一些sed编辑器提供的高级特性. 21.1 多行命令 按照之前的知识,所有的sed编辑器命令都是针对单行数据执行操作的. 在sed编辑器读取数据流时,它会基于换行符的位置将数据分成行,一次处理 ...
- 《Linux命令行与shell脚本编程大全》第十一章 构建基本脚本
11.1使用多个命令 $date;who // 命令列表,加入分号就可以,这样会依次执行.参见5.2.1节 注意区分$(date;who),这个是进程列表,会生成一个子shell来执行 Shel ...
- 《Linux命令行与Shell脚本编程大全第2版》读书笔记
公司说不准用云笔记了,吓得我赶紧把笔记贴到博客上先..... 近3年前的了,只有一半的章节,后面的没空记录了.... 第1章 可以cat /proc/meminfo文件来观察Linux系统上虚拟内存的 ...
- 《Linux命令行与shell脚本编程大全》第十七章 创建函数
可以将shell脚本代码放进函数中封装起来,这样就能在脚本中的任何地方多次使用它了. 17.1 基本的脚本函数 函数:是一个脚本代码块,可以为其命名并在代码中任何位置重用. 17.1.1 创建函数 有 ...
随机推荐
- Linux06--Shell程序设计02 数据流重定向与管道
包含3种数据流: •标准输入(stdin):代码为0,符号为<或<<; •标准输出(stdout):代码为1,符号为>或>>; •标准错误输出(stderr):代码 ...
- python 学习day6(面向对象)
博客部分内容转自:http://www.cnblogs.com/wupeiqi/p/4493506.html 面向对象编程介绍 为什么要用面向对象进行开发? 面向对象的特性:封装.继承.多态 类.方法 ...
- 学习使用Free RTOS ,移植最新的STM32 v3.5固件库
最近拿到了一块万利的EK-STM32F的学习板,打算先用它来熟悉下STM32的编程环境,不过在这过程中和一个同事聊的时候觉得如果只调用STM32的库写程序,可能在芯片资源的利用上面可能就会差一点,在这 ...
- org.springframework.context.event.AbstractApplicationEventMulticaster
private Collection<ApplicationListener<?>> retrieveApplicationListeners(ResolvableType e ...
- 外网如何访问本地tomcat web服务器【转】
转自:http://jingpin.jikexueyuan.com/article/49159.html 外网如何访问本地tomcat web服务器 作者: XHKJOE 发布时间:2015-07-1 ...
- mysql允许远程IP访问
默认情况下Linux内的mysql数据库mysql,user表内的用户权限只是对localhost即本机才能登陆.需要更改权限: mysql> Grant all privileges on * ...
- MySQL优化GROUP BY-松散索引扫描与紧凑索引扫描
满足GROUP BY子句的最一般的方法是扫描整个表并创建一个新的临时表,表中每个组的所有行应为连续的,然后使用该临时表来找到组并应用累积函数(如果有).在某些情况中,MySQL能够做得更好,即通过索引 ...
- 新手求大神,有其他swit-case的思路写这个程序么?
两个程序: switch-case与if-else if的区别相同点:可以实现多分支结构;不同点:switch:一般只能用于等值比较.(可以进行范围运算???---学会用switch计算范围出炉的思路 ...
- JavaSE复习日记 : 循环终止语句(break/break outerFor/continue)
最近没网,但攒了几天的博客,这次逮到机会发博客,直接三篇走起; /* * 循环终止语句: break/ break outerFor/ continue */ /* * break语句 * 1. 用于 ...
- google base库中的WaitableEvent
这个类说白了就是对windows event的封装,没有什么特别的,常规做法,等侍另一线程无非就是等侍事件置信waitsingleobject,通知事件无非就是setevent,一看就明白,不就详解, ...