Shell--呈现数据

文件描述符

#文件描述符来标识每个文件对象,唯一的标识会话中打开的文件
#0 stdin 1 stdout 2 stderr
#使用<时,Linux会用重定向指定的文件替换标准输入文件描述符
#命令行中只输入cat命令,它会接受stdin 的输入
#也可以使用重定向符号接受非stdin的输入
cat < testfile
#输出重定向来改变输出,将显示到显示器的输出定向到指定的重定向文件
ls -l > test2
#追加数据
who >> test2
#shell处理错误消息和处理普通输出是分开的
#默认情况下,stdout,stderr文件描述符指向同样的地方,显示器
#重定向错误
#只重定向错误,2>是紧连在一起的
ls -al badfile 2> test4
#重定向错误和数据
#在重定向的每个数据前添加对应的文件描述符,将它们指向对应的保存数据的输出文件
ls -al test test2 test3 badtest 2> test6 1> test7
#同样也可以将stderr和stdout输出重定向到同一个输出文件
ls -al test test2 test3 badtest &> test7
#bash shell会自动给错误消息分配较标准输出来说更高的优先级
#这样就可以在一处地方查看错误消息了```

###脚本中重定向输出

用stdout和stderr文件描述符来在多个位置生成输出,重定向相应的文件描述符

临时重定向

在脚本中生成错误消息,将某一行输出重定向到stderr

echo “this is an error message” >&2

所以如果脚本重定向了stderr,就会将上条消息输出到重定向的文件

./test8 2> test9“`

永久重定向

#exec命令使shell在脚本执行期间重定向某个特定文件描述符
#重定向每个echo语句
exec 1>testout
echo "this is a test"
#exec命令会启动一个新shell并且将stdout文件描述符重定向到文件
#脚本中发给stdout的所有输出都会被重定向到文件
exec 2>testerror
echo "this is the start of the script"
exec 1>testout
echo "i love you"
echo "but this should go to the testerror file" >&2
#因此这里testout会包含正常信息,testerror则包含错误信息
#在定义1>testout之前的echo还是会输出到屏幕上的```

###在脚本中重定向输入

exec命令将stdin重定向到linux系统上的文件中

!/bin/bash

exec 0< testfile
count=1
while read line;do
echo “line #$count: $line”
count=$[ $count + 1 ]
done

读取日志文件的最简单办法“`

创建输出文件描述符

#shell中最多可以有9个打开的文件描述符,另外6个是3-8
exec 3>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```

###重定向文件描述符

将文件描述符3重定向到文件描述符1的位置,也就是显示器

类似于引用,显示器的引用,重定向文件的引用

exec 3>&1

将文件描述符1重定向到文件,但是3仍然指向显示器

exec 1>test14out
echo “this should store in the output file”
echo “along with this line”

将1重定向3的位置,也就是显示器

exec 1>&3
echo “now things should be back to normal”“`

创建输入文件描述符

#先将stdin文件描述符保存到另外一个文件描述符,读取完重定向文件后再恢复
exec 6<&0
exec 0< testfile
count=1
while read line;do
    echo "Line #$count: $line"
    count=$[ $count + 1 ]
done
exec 0<&6
read -p "are you done now?" answer
case $answer in
    y|Y) echo "goodbye";;
    N|n) echo "sorry, this is the end";;
esac```

###创建读写文件描述符

使用同一个文件描述符来从文件中读写数据

exec 3<> testfile
read line <&3
echo “Read: $line”
echo “this is a test line” >&3

因为shell中会维护一个读写文件的位置指针

因此读取之后,指针的位置将作为下一次读写的位置

如果写入的话,就会从这个位置开始覆盖原有的数据“`

关闭文件描述符

#shell会在脚本退出时自动关闭它们
#手动关闭文件描述符
exec 3>&-
#下面是一个例子,最后会出现错误,一旦关闭了,就不能再使用了
exec 3> test17file
echo "this is a test line of data" >&3
exec 3>&-
echo "this won't work" >&3```

###列出打开的文件描述符

lsof -a -p $$ -d 0,1,2

-a选项是对后面两个选项的结果执行布尔and运算

-p指定进程PID,$$表示当前进程的PID

-d表示允许指定要显示的文件描述符的个数

FD那一列中,数字表示文件描述符,u表示读写,w表示写,r表示读“`

阻止命令输出

ls -al > /dev/null
#阻止任何错误消息但是不保存
ls -al badfile test16 2> /dev/null
#也可以在输入重定向将/dev/null作为输入文件
#从而快速移除现有的文件中的数据而不用先删除文件再创建,bingo
cat /dev/null > testfile```

###创建本地临时文件

mktemp会在本地目录中创建一个临时文件

指定文件名模板,

mktemp testing.XXXXXX

mktemp会用6个字符码替换这6个X,保证文件名在目录中是唯一的,返回文件名

将文件名保存到变量中,就可以在后面脚本中引用了

tempfile=mktemp test19.XXXXXX
exec 3>$tempfile
echo “this script writes to temp file $tempfile”
echo “this is the first line” >&3
echo “this is the second line” >&3
exec 3>&-
echo “done creating temp file, the contents are:”
cat $tempfile
rm -f $tempfile 2> /dev/null“`

在/tmp目录创建临时文件

#-t选项会在系统的临时目录创建文件,返回全路径
mktemp -t test.XXXXXX
#比如返回/tmp/test.XG3374
tempfile=`mktemp -t tmp.XXXXXX`
echo "this is a test file" > $tempfile
echo "this is the second line" >> $tempfile
echo "the temp file is located at: $tempfile"
cat $tempfile
rm -f $tempfile```

###创建临时目录

-d选项使其创建一个临时目录

tempdir=mktemp -d dir.XXXXXX
cd $tempdir
tempfile1=mktemp temp.XXXXXX
tempfile2=mktemp temp.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“`

tee命令

#将stdin过来的数据重定向
date | tee testfile
#默认情况下,tee命令会在每次使用时覆盖输出文件内容
#使用-a来将数据追加过去
date | tee -a testfile```
    原文作者:KevinCool
    原文地址: https://www.jianshu.com/p/b65b49de18f9
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞