shell 输出

脚本输出的方法:
1、在显示屏幕上显示输出
2、将输出重定向到文件中。


标准文件描述符
Linux系统将每个对象当做文件来处理,这包括输入和输出的过程
linux用文件描述符来标识每个文件对象。文件描述符是一个
非负整数,可以唯一地标识会话中打开的文件,每个过程一次
最多可以有9个文件描述符,出于特殊目的,bash shell 保留了
最早的3个文件描述符(0、1、2)。
文件描述符       缩写      描述 
0    STDIN        标准输入
1                  STDOUT    标准输出
2                   STDERR    标准错误


如何重定向错误的消息
1、只重定向错误
STDERR文件描述符被设成2,你可以选择只重定向错误消息,
将该文件描述符值放在重定向符号前,该值必须紧紧地放在
重定向符号前,否则不工作。
ls  -al badfile  2> test.txt


2、重定向错误和数据
如果你想重定向错误和正常输出,你必须用两个重定向符号
你需要在想要重定向的每个数据前添加对应的文件描述符,
并将他们指向对应的保存数据的输出文件:
ls -al test test2 test3 badfile  2>test.err  1>test.txt


另外,如果你愿意,你也可以使用特殊的重定向符号&>,
将正常输出和错误输出重定向到一个输出文件。此时,bash
shell会自动给错误的消息分配较标准输出来说更高的优先级,
因此,错误的消息会在重定向的文件的一处集中显示,方便
人员查看。
ls -al test  badfile  &>test.err


临时重定向
如果需要把正常输出定义到错误输出,可以使用输出重定向
符来将输出重定向到STDERR文件描述符,在重定向到文件
描述符时,你必须在文件描述符数字之前加一个and符(&)
echo  "This is an error message"  >&2


永久重定向
如果脚本中有大量数据需要重定向,那重定向每个echo语句
就会很烦琐,取而代之,你可以用exec命令告诉shell在脚本
执行期间重定向某个特定文件描述符。
#!/bin/bash
# reading all  about to a file
exec 1>testout
echo "this is a good stop"
echo "what do you do?"
echo "your dog chasing my cat"


在脚本中重定向输入
exec命令允许你将STDIN重定向到linux系统上的文件中:
exec  0<  testfile
这个命令会告诉shell它应该从文件testfile中获得输入,而不是
STDIN,这个重定向只要在脚本需要输入时就会作用。
#!/bin/bash
# redirecting file input
exec 0< 11.sh
count=1


while read line
do
echo "line #$count: $line"
count=$[ $count + 1 ]
done
当read命令从键盘读取输入的时候,这时候会从文件读取。


创建自己的重定向
1、创建输出文件描述符
你可以用exec命令给输出分配文件描述符,和标准的文件描述符一样,
一旦你给一个文件位置分配了另外一个文件描述符,那个重定向
就会一直有效,直到你重新分配。
exec 3>test3out
echo "this is a dog"  >&3


从已重定向的文件描述符中恢复
#!/bin/bash
# storing STDOUT . then coming back to it
exec 3>&1
exec 1>test11out


echo "i have one younger sister and two older brothers"
echo "we are not rich,but we are a happy family"


exec 1>&3


echo "it's over!"
其中exec命令的使用把重定向恢复到了默认值。是恢复设置
的通常做法。


关闭文件描述符
我们在脚本中创建新的文件描述符,在脚本运行结束后会
自动关闭,但是有时候我们需要在脚本运行中关闭文件描述符
可以进行如下操作:
要关闭文件描述符,将它重定向到特殊符号&-
exec   3>&-
该语句会关闭文件描述符3,从而阻止在脚本中使用它。
一旦关闭文件描述符,你就不能在脚本中想它写入任何数据
,否则shell会生成错误消息。还要注意,如果你在脚本的后面
打开了同一个输出文件,shell会用一个新文件来替换已有文件


列出打开的文件描述符 
lsof命令会列出整个linux系统打开的所有文件描述符 ,这是个
有争议的功能,因为它会向非管理员用户提供linux系统的信息
如果是普通用户来运行它,我必须通过全路径名来引用它
有足够的命令行选项和参数帮助过滤lsof的输出,最常用的 有
-p和-d,前者允许指定进程ID,后者允许指定要显示的文件描述符
个数。
要知道该进程的当前PID,你可以用特殊环境变量$$(shell会
将它设为当前PID),-a选项用来对其他两个选项执行布尔and
运算,
lsof -a -p $$ -d 0,1,2
默认输出的信息:
command     正在运行的命令名的前9个字符
PID   进程的pid
user 进程属主的登录名
fd                 文件描述符数目以及访问类型(r代表读,w代表
写,u代表读写)
type 文件类型(chr代表字符型,blk代表块型,dir代表
目录,reg代表常规文件)
device 设备的设备号(主设备号和从设备号)
size 如果有的话,文件的大小
node 本地文件的节点
name 文件名


阻止命令输出
有时候你不想显示脚本的输出,这在将脚本作为后台进程执行
时很常见。
我们可以讲STDERR重定向到一个称作null文件的特殊文件,null
文件跟它的名字很像,文件里什么都没有,shell输出到null文件
的任何数据都不会保存,这样他们就都被丢掉了。
在linux系统中null文件的标准位置是/dev/null
阻止任何错误消息而不保存它们的一个通用方法:
ls  -al badfile test  2>/dev/null


你也可以在输入重定向将/dev/null作为输入文件,由于/dev/null
文件不含有任何内容,程序员通常用它来快速移除现有文件中
的数据而不用先删除文件在创建。




创建临时文件
linux使用/tmp目录来存放不需要一直保留的文件(即临时文件)
大多数linux发行版配置了系统启动时自动删除/tmp目录
的所有文件。
系统上的任何用户账户都有权限在/tmp目录中读和写。
mktemp命令可以在/tmp中创建一个唯一的临时文件,而不使用
默认的umask值。它将文件的读写权限分配给文件的属主。其他
人无法访问,root用户除外。
默认情况下,mktemp会在本地目录中创建一个文件,要用mktemp
命令在本地目录中创建一个临时文件,你只要指定一个文件名
模版就行了,模版可以包含任意文本文件名,在文件名末尾加
上6个X就行了。
-t选项会强制mktemp命令来在系统的临时目录来创建该文件,在
用这个特性时,mktemp命令会返回用来创建临时文件的全路径,
而不只是文件名。
-d选项告诉mktemp命令来创建一个临时目录而不是临时文件。




记录消息
有时将输出一边发送到显示器一边发送到日志文件,用特殊命令
tee就行。
tee命令相当于管道的一个T型接头,它将从STDIN过来的数据
同时发给两个目的地。
tee filename
注意tee命令会在每次使用时覆盖输出文件内容,如果你想将
数据追加到文件中,必须使用-a选项。

你可能感兴趣的:(linux,shell,运维)