15 阅读笔记呈现数据

文章详细介绍了Linux系统中如何理解和使用文件描述符,特别是标准输入(0)、标准输出(1)和标准错误(2)。内容涵盖重定向输出和错误,如将输出和错误分别重定向到文件,以及如何在脚本中创建和管理自定义的输出和输入重定向。此外,还讨论了创建临时文件和使用`tee`命令记录消息的方法。
摘要由CSDN通过智能技术生成

15. 呈现数据

15.1 理解输入和输出

15.1.1 标准文件描述符
Linux系统将每个对象当作文件处理。Linux用文件描述符(file descriptor)来标识每个文件对象。文件描述符是一个非负整数,可以唯一标识会话中打开的文件。每个进程一次最多可以有九个文件描述符。出于特殊目的,bash shell保留了前三个文件描述符(0、1和2)。
文件描述符详解

15.1.2 重定向错误
只重定向错误: STDERR文件描述符2必须紧紧地放在重定向符号前,否则不会工作。

#当前目录下面正常来说没有badfile,因此ls -al badfile会报错
#2>将错误输出信息重定向到test4
ls -al badfile 2> test4

使用STDOUT和STDERR消息混杂在同一输出例子,命令执行结果:

#如果test或者badtest或者test2有一个存在于当前目录,则是STDOUT,或者是STDERR输出重定向到test5
$ ls -al test badtest test2 2> test5 
-rw-rw-r-- 1 rich rich 158 2014-10-16 11:32 test2 
$ cat test5 
ls: cannot access test: No such file or directory 
ls: cannot access badtest: No such file or directory

重定向错误和数据: 重定向错误和正常输出,必须用两个重定向符号,相关命令执行结果:

#列举test test2 test3 badtest三个文件信息, 将STDERR 2重定向到test6 STDOUT重定向到test7
$ ls -al test test2 test3 badtest 2> test6 1> test7 
$ cat test6 
ls: cannot access test: No such file or directory 
ls: cannot access badtest: No such file or directory 
$ cat test7 
-rw-rw-r-- 1 rich rich 158 2014-10-16 11:32 test2 
-rw-rw-r-- 1 rich rich   0 2014-10-16 11:33 test3

如果想要将STDOUT和STDERR重定向到同一个输出文件,应该使用&>,执行结果为:

$ ls -al test test2 test3 badtest &> test7 
$ cat test7 
ls: cannot access test: No such file or directory 
ls: cannot access badtest: No such file or directory 
-rw-rw-r-- 1 rich rich 158 2014-10-16 11:32 test2 
-rw-rw-r-- 1 rich rich   0 2014-10-16 11:33 test3

15.2 重定向输出

临时重定向
在脚本中将错误信息重定向到STDERR,然后在运行的时候将STDERR重定向到某个文件。

#!/bin/bash 
# 将这行信息重定向到STDERR
echo "This is an error" >&2 
echo "This is normal output"

执行的时候一定要重新将STDERR重定向到某个文件,才能看出区别。默认将STDERR输出到STDOUT,因此,执行及结果为:

$ ./test8 2> test9 
This is normal output 
$ cat test9 
This is an error

永久重定向
如果脚本中有大量数据需要重定向,上述方法不适合,因为需要将每条消息输入到STDERR。可以使用exec告诉shell在脚本执行期间重定向到某个特定文件描述符。

exec 1>testout    #将STDOUT重定向到testout
exec 2>testerror  #将STDERROR重定向到testerror

示例代码:

#!/bin/bash 
# redirecting output to different locations 
 
exec 2>testerror 
 
echo "This is the start of the script" 
echo "now redirecting all output to another location" 
 
exec 1>testout 
 
echo "This output should go to the testout file" 
echo "but this should go to the testerror file" >&2  #如果不使用&2,这代表将这条消息重定向到名称为2的文件中

执行结果:

$ ./test11 
This is the start of the script 
now redirecting all output to another location 
$ cat testout 
This output should go to the testout file 
$ cat testerror 
but this should go to the testerror file

可以将echo语句的输出发给STDERR,一旦重定向了STDOUT或STDERR,就很难再将它们重定向回原来的位置。

15.3 在脚本中重定向输入

exec 0< filename  #从文件名为filename的文件中获得输入

示例代码:

#!/bin/bash 
# redirecting file input 
 
exec 0< testfile 
count=1 
 
while read line 
do 
   echo "Line #$count: $line" 
   count=$[ $count + 1 ] 
done

执行结果:

$ ./test12 
Line #1: This is the first line. 
Line #2: This is the second line. 
Line #3: This is the third line.

15.4 创建自己的重定向

15.4.1 创建输出文件描述符

#!/bin/bash
exec 3>test13out  #test13out就是输出文件描述符
 
echo "This should display on the monitor" 
echo "and this should be stored in the file" >&3 
echo "Then this should be back on the monitor"

exec追加到现有文件

exec 3>>test13out

15.4.2 重定向文件描述符
还原文件描述符的重定向,就是将重定向的文件描述符重新转换回去,看下列代码:

#!/bin/bash 
# storing STDOUT, then coming back to it 
 
exec 3>&1   #将文件描述符3重定向到STDOUT
exec 1>test14out  #将STDOUT重定向到test14out文件中
 
echo "This should store in the output file" 
echo "along with this line."

exec 1>&3  #将STDOUT重定向到文件描述符3就是将这个还原了
echo "Now things should be back to normal"

15.4.3 创建输入文件描述符
按照重定向输出描述符同样的方法重定向输入文件描述符

#!/bin/bash
exec 6<&0  #将键盘输入重定向到6号文件描述符
exec 0< testfile #将testfile作为STDIN标准输入

count=1
while read line
do
  echo "Line #$count:$line"
  count=$[ $count + 1 ]
done

exec 0<&6  #将6号文件描述符键盘输入返还给STDIN
read -p "Are you done now?" answer

case $answer in
Y|y) echo "Goodbye";;
N|n) echo "Sorry, This is the end.";;
esac

15.4.4 创建读写文件描述符
对同一个文件进行数据读写,shell会维护一个
内部指针,指明在文件中的当前位置。任何读或写都会从文件指针上次的位置开始。

示例代码:

#!/bin/bash
exec 3<> testfile   #将testfile作为3号文件描述符号的输入输出
read line <&3   #读取了第一行并打印了出来
echo "Read: $line"   
echo "This is a test line" >&3  #修改了第二行的内容

执行结果:
运行结果
15.4.5 关闭文件描述符
如果你创建了新的输入或输出文件描述符,shell会在脚本退出时自动关闭它们。然而在有些情况下,你需要在脚本结束前手动关闭文件描述符。运行命令:

exec fd(file descriptor)>&-

一旦关闭了文件描述符,就不能在脚本中向它写入任何数据,否则shell会生成错误消息。 在关闭文件描述符时还要注意另一件事。如果随后你在脚本中打开了同一个输出文件,shell会用一个新文件来替换已有文件。这意味着如果你输出数据,它就会覆盖已有文件。

示例代码:

#!/bin/bash
exec 3> test_new_file #将文件描述符3重定向test_new_file
echo "This is a test line of data" >&3  #将信息输入文件描述符3
exec 3>&- #停止当前文件描述符的操作

#再次打开
cat test_new_file

exec 3> test_new_file    #如果将这行改为exec 3>> test_new_file则不会出现上述问题
echo "This is a new test line of data" >&3

15.5 列出打开的文件描述符

记住哪个文件描述符被重定向到了哪里很难,因此使用lsof命令。但是它会向非系统管理员用户提供Linux系统的信息,因此一般会隐藏这条命令,需要/usr/sbin/lsof来引用,这会打印很多的输出。

选项作用
-p指定进程ID($$一般默认当前进程)
-d显示的文件描述符编号
-a一般是对操作做与运算

执行lsof -a -p $$ -d 0,1,2执行结果lsof输出详解
在这里插入图片描述在这里插入图片描述

15.6 阻止命令输出

很多时候,会将无关痛痒的小错误也打印出来或者发送给进程的属主。为了解决这个问题,可以将STDERR重定向到null文件,null文件在linux的标准位置为/dev/null。

ls -al badfile test16 2> /dev/null

同时由于/dev/null文件不含有任何内容,程序员通常用它来快速清除现有文件中的数据,而不用先删除文件再重新创建。

cat /dev/null > testfile

15.7 创建临时文件

15.7.1 创建本地临时文件
mktemp会在本地目录中创建一个文件。命令格式为mktemp filename.XXXXXX
执行错误
注意:x一定要大写

在脚本中使用mktemp必须将文件名保存到变量,然后继续引用

#!/bin/bash

tempfile=$(mktemp testing.XXXXXX)

exec 3> $tempfile #将文件描述符3重定向到tempfile

echo "This is the first line." >&3
echo "This is the second line." >&3
echo "This is the third line." >&3
exec 3>&-    #关闭3号文件描述符

#执行完毕之后删除临时文件,将错误信息不打印出来
echo "Done creating temp file, the content are:"
cat $tempfile
rm -f $tempfile 2> /dev/null

15.7.2 在/tmp目录创建临时文件
-t选项会强制mktemp命令来在系统的临时目录来创建该文件。在用这个特性时,mktemp命令会返回用来创建临时文件的全路径,而不是只有文件名。因此可以在任何脚本下使用这个路径引用这种方式生成的临时文件。

15.7.3 创建临时目录
-d选项告诉mktemp命令来创建一个临时目录而不是临时文件。

#!/bin/bash
tempdir=$(mktemp -d dir.XXXXXX)
cd $tempdir
tempfile1=$(mktemp tmp.XXXXXX)
tempfile2=$(mktemp tmp.XXXXXX)
exec 7> $tempfile1
exec 8> $tempfile2

echo "Sending data to directory $tempdir"
echo "This is a test line of data for $tempfile1" >&7
echo "This is a test line of data for $tempfile2" >&8

15.8 记录消息

tee命令相当于管道的一个T型接头。它将从STDIN过来的数据同时发往两处。一处是STDOUT,另一处是tee命令行所指定的文件名:

tee filename

使用管道重定向数据,这样会重写testfile内容,-a是对文件追加数据,

date | tee testfile
date | tee -a testfile
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值