文件描述符是和文件输入,输出相关的整数,用来跟踪已经打开的文件,常见的文件描述符是stdin,stdout,sderr,将某个文件描述符的内容重定向到另一个描述符中,下面给出一些对文件描述符进行操作或者重定向的雷子
我们编写脚本的时候,频繁使用标准输入stdin 标准输出 stdout 标准错误 stderr
将内容过滤并且重新定向到文件是一个从事的基本任务,当命令输出文本的时候,这些输出的文本可能是错误信息,也可能是正常的输出信息,我们通过文件描述符来解决这个问题,将这些和特定描述符相关的文本提取出来
文件描述符是和一个打开的文件和数据流相关联的整数,文件描述符 0 1 2是系统预留的
0 标准输入
1 标准输出
2 标准错误
我们演示下,如何将文本重定向到一个文件之中
echo “This is a sample text” > temp.txt
我们将这个语句以覆盖的方式,进行写入到文件中,之前的内容会被清除掉
如果是追加的话
echo “This is a sample text” >> temp.txt
>是覆盖, >> 是追加到文件的尾部
然后查看对应的文件内容
cat temp.txt
直接使用 >> 的话,重定向的内容不会出现在终端上输出,而是直接导给了文件,重定向操作符默认使用标准输出,如果使用特定的文件描述符,必须将描述符置于操作符之前 > 等于1> >>等于 1>>
但是在输出标准错误的时候,会在终端上显示出来
比如下面的信息
$ls +
会爆出一个错误信息,因为 + 是一个非法的参数,就会返回错误的信息
如果改为如下的命令,那么可能会重新定向到文件中去
$ls + 2> err.txt
所以,对于可能存在问题抛出的指令
可以将err定向到一个文件, out定向到另外一个文件
$cmd 2>stderr.txt 1>stdout.txt
或者使用如下的语句,将stderr转换为stdout,使得这两个都去输出到了一个文件中
$cmd > output.txt 2>&1
最终的方式是
$cmd $>output
对于输出出来的一些不必要的信息,如果不想要的话,可以利用stderr的输出重定向到 /dev/null
来确保一切都被清除掉了,
假如有三个文件,分别为a1,a2,a3,普通用户对a1没有读 写 执行的权限如果需要打印所有以a为开头的文件的内容,可以使用cat 命令,但是会爆出错误
对于这种错误信息,我们想要单独保留下来,可以使用 stderr将信息重定向到一个文件中,并且stdout保持不变
cat a* 2>err.txt
或者利用linux的黑洞文件,来保证输出的纯洁性
cat a* 2> /dev/null
stderr的输出被丢在了文件/dev/null之中,在/dev/null里面是一个特殊的设备文件,这个文件会将接收到的所有数据都通通丢弃,因此,null设备被称为位桶 或者黑洞
当对stderr或者stdout进行重定向的时候,重定向的文本或将传入文件,因为所以已经不会有东西通过管道(|)传入后续命令了,而这些命令通过stdin来接收文本的
但是并非绝对,可以使用别的方式将数据重定向到文件,并且提供给后面命令stdin,要通过tee来实现,
我们在打印一个文件的时候,同时将其重定向到一个文件中,可以这样使用tee
command | tee FILE1 FILE2
在下面,我们一边接受来自stdin的数据,将stdout的一份副本写入out.txt中,同时将另外一份副本作为后续命令的stdin,命令cat -n 将stdin中接收到的每一行数据前面加上行号并且写入stdout
$cat a* | tee out.txt |cat -n
然后查看out.txt的内容
tee命令会将其文件覆盖,但是tee提供了一个-a的选项,可以用于去追加内容
同样可以使用stdin作为命令参数,只要将-作为命令的文件名参数就可以了
例如
$echo who is this | tee-
或者将 /dev/stdin作为输出文件名使用stdin
类似的,使用 /dev/stderr代表标准错误, /dev/stdout代表标准输出,这些分别代表的stdin stdout stderr
补充说明
从stdin读取输入的命令可以多种方式去接收数据,但是我们可以用cat和管道来指定我们自己的文件描述符,例如:
$cat file | cmd
$cmd1 | cmd2
1.文件重定向到命令
借助重定向,可以像使用stdin那样从文件那里读取文件
$cmd < file
2.重定向脚本内部的文本块
我们需要对文本块像是标准输入一样进行重定向,先从一个文件中读取,在写入另外的文件中
在cat <<EOF> log.txt和下一个EOF行之间的所有文本行都会被当做stdin数据
后面可以加上 | tee -a xx.txt
自定义文件描述符
文件描述发是一个用于访问文件的一个抽象指针,存取文件离不开被称为文件描述发的特殊字符, 0代表stdin 1代表stdout
我们可以使用exec命令创建自定义的文件描述符,如果对其他的编程语言进行文件编程非常熟悉
可以利用exec命令创建自定义的文件描述符,如果对其他的编程语言进行文件编程很熟悉,可能已经发现了文件打开模式,有三种模式
只读模式
截断模式
追加模式
<操作符用于从文件中读取至stdin, >操作符用于截断模式下的文件写入
>>操作符用于追加模式的文件写入(数据被添加到文件现有内容后)
我们如何自定义一个文件描述符
echo this is a test line > input.txt
exec 3<input.txt
然后,在命令中使用文件描述符3
cat <&3
this is a test line
创建一个文件描述符用于写入
exec 4>output.txt #打开文件用于写入
例如
$exec 4>output.txt
$echo newline >&4
$cat output.txt
newline
创建一个文件描述符用于追加写入文件的操作
exec 5>>input.txt
echo appended line >&5
cat input.txt