在Linux中存在三个标准文件描述符:
文件描述符 | 缩写 | 描述 |
0 | STDIN | 标准输入 |
1 | STDOUT | 标准输出 |
2 | STDERR | 标准错误 |
STDIN代表标准输入,对于终端来说,标准输入是键盘,我们可以使用"<"重定向标准输入
STDOUT代表标准输出,对于终端来说,标准输出是终端显示器,shell中的所有输出包括shell中运行的程序和脚本都默认输出到显示器,我们可以通过">"来重定向输出
STDERR在linux中标准输出和错误输出是不相同的,但是在运行shell的时候错误输出会和标准输出同时显示在显示器上,那么他是因为:Linux会将STDERR导向STDOUT
命令行中重定向输出
ls -l testt test 1>testout 2>testerror
目录下只包含test文件,没有testt文件,所以标准输出被重定向到了testout中,而错误信息被重定向到了testerror中,那么将两个重定向到一个文件中要使用:
ls -l testt test &>testout
为了避免错误信息散落在文件中,相较于标准输出,bash shell会自动赋予错误信息跟高的优先级,所以错误信息一般会在标准输出之上
在脚本中重定向输出
#!/bin/bash
echo "This is an error" >&2
echo "This is a normal output"
在脚本中重定向的格式就是如上面所示,但是在执行脚本的时候,没有将“This is an error”重定向到STDERR,因为Linux会将STDERR导向STDOUT,所以,如果我们这样测试,就会得到我们想要的结果
上面所说的方法只是临时重定向,当然我们还有永久重定向,需要使用exec命令告诉shell在脚本执行期间重定向指向某个特定的文件描述符。
#!/bin/bash
exec 2>testerror
echo "this is the first line"
exec 1>testout
echo "this is the second line"
echo "this is the thrid lind and it's an error output">&2
同样,为了防止将STDERR导向STDOUT,我们要在里面使用">&2"表示将输出重定向到STDERR。
脚本中重定向输入
#!/bin/bash
exec 0<testfile
count=1
while read line
do
echo "the $count line is : $line"
count=$[ $count + 1 ]
done
可以看到read命令的输入部分,被重定向到了testfile中
创建自己的重定向
在shell中最多有9个打开的文件描述符,0-2上面提到的,3-8文件描述符均可作为输入或者输出重定向。
#!/bin/bash
exec 3>testout
echo "This is a formal ouput!"
echo "This is the second line"
也可以在文件后追加内容,使用:
exec 3>>testout
我们知道了怎么重定向到对应的文件,但是怎么恢复重定向的文件描述符?可以分配一另外一个文件描述符给标准文件描述符,也就是可以将STDOUT的原来位置重定向到另外一个文件描述符,然后再利用该文件描述符重定向会STDOUT
#!/bin/bash
exec 3>&1
exec 1>testout
echo "appears in the file testout"
echo "along with this line"
exec 1>&3
echo "Now things should be back to normal"
可以看到在使用exec 1>3&之后,STDOUT又回到了显示器,也就是之前的值
现在,看一下,如何创建标准输入文件描述符(和上面不同的是:使用'<'符号,以及默认STDIN为0)
#!/bin/bash
exec 6<&0
exec 0<testfile
count=1
while read line
do
echo "the $count line is: $line"
count=$[ $count + 1 ]
done
exec 0<&6
read -p "Enter your name:" name
echo "Hello $name!"