Shell文件描述符和重定向

Linux系统中,每当进程打开一个文件时,系统就为其分配一个唯一的整型文件描述符,用来标识这个文件。大家知道,标C中,每个进程默认打开的有三个文件,标准输入、标准输出、标准错误输出,分别用一个FILE结构的指针来标示,即stdin、stdout、stderr,这三个结构中分别维护着三个文件描述符0、1、2。

Shell中,0、1、2也是默认可用的三个文件描述符。为了利用其他文件描述符来标识特定文件,我们需要使用exec命令打开该文件,并指定一个数字作为描述符,文件符range是0-9.

因为0是标准输入,1是标准输出,2是标准错误,所以没有特别缘由,我们使用3-9.

举例:

  1. exec 3 以只读方式文件打开/tmp/1.txt文件,文件描述符对应为3
  2. exec 3>/tmp/1.txt
    写方式打开/tmp/1.txt,文件描述符对应为3
  3. exec 3<>/tmp/1.txt
    读写方式打开/tmp/1.txt,文件描述符对应为3
  4. exec 3<&-
    关闭文件描述符3

附录:常用文件重定向命令

command > filename                          把标准输出重定向到一个新文件中
command >> filename                        把标准输出重定向到一个文件中(追加)
command 1 > fielname                       把标准输出重定向到一个文件中
command > filename 2>&1                  把标准输出和标准错误一起重定向到一个文件中,即把两组输出都重定向到一个文件中,使用>&
command 2 > filename                       把标准错误重定向到一个文件中
command 2 >> filename                     把标准输出重定向到一个文件中(追加)
command >> filename 2>&1                把标准输出和标准错误一起重定向到一个文件中(追加)
command < filename >filename2          把command命令以filename文件作为标准输入,以                                              filename2文件作为标准输出

command < filename                         把command命令以filename文件作为标准输入
command << delimiter                       把从标准输入中读入,直至遇到delimiter分界符
command <&m                                 把文件描述符m作为标准输入
command >&m                                 把标准输出重定向到文件描述符m中
command &m<&-                              关闭文件描述符m


例子:
1.txt:

this is 1.txt

$exec 3<1.txt

$cat <&3 输出:this is 1.txt

默认:cat  > url

url1

url2

ctrl+c终止

cat > url << end

url1

url2

end 输入end终止

完成后rul内容都为:

url1

url2

普通重定向:

cmd n > file,如cmd 1>file代表标准输出的描述符1被重定向文件file,即cmd的标准输出会输出到file
cmd n >> file 追加
cmd n < file

例子:
echo "test" 1>file
cat file输出test
read a 0<1.txt
echo $a输出内容为1.txt中的第一行,行末的换行表示输入结束


重定向标准输出和标准错误到单独的文件:
cmd 1 > file1 2> file2可以简化为:cmd > file1 2> file2
cmd >> file1 2> file2
cmd > file1 2>> file2
cmd >> file1 2>> file2
例子:
cat "abcd" 1> file1 2> file2 cat命令的标准输出会输出到file1,cat命令的标准错误输出会输出到file2
ln -s src dest >> mylod 2> /dev/null ln命令的STDOUT被追加到文件mylog,STDERR被重定向到文件/dev/null

重定向标准输出和标准错误输出到同一个文件:
cmd > file 2>& 输出
cmd >> file 2>& 将标准输出和标准错误追加到文件
exec n>&m
n是一个新文件描述符,而m是一个已经打开的输出文件描述符,复制一个已经打开的输出文件描述符,如:
exec 4>out.txt
exec 5>&4
执行后,文件描述符5会成为描述符4的复制品.
echo "str" 1>&5, out.txt的内容将为str

exec n<&m, n为m的复制品

关闭文件描述符:
exec n>-
如:exec 4>- 关闭文件描述符4
例子:
exec 4>5.txt; 以写方式打开5.txt,文件描述符对应为4
echo "str" 1>&4; 标准输出到文件描述符为4的文件,即5.txt
cat 5.txt 输出str
再次执行:echo "str" 1>&4; 5.txt的内容为:
str
str
故其为追加。
exec 1>fd.out把标准输出重定向到fd.out文件中,如果执行echo "good",屏幕上将不会显示good,good会被输出到fd.out中去。


转载地址:http://blog.chinaunix.net/uid-1829236-id-3173217.html

例子:

#显示当前目录文件 test.sh test1.sh test1.sh实际不存在
[chengmo@centos5 shell]$ ls test.sh test1.sh
ls: test1.sh: 没有这个文件和目录
test.sh
#将错误输出信息关闭掉
[chengmo@centos5 shell]$ ls test.sh test1.sh 2>&-
test.sh
#&[n] 代表是已经存在的文件描述符,&1 代表输出 &2代表错误输出 &-代表关闭与它绑定的描述符

#关闭所有输出
[chengmo@centos5 shell]$ ls test.sh test1.sh  1>&- 2>&-
#关闭 1 ,2 文件描述符

[chengmo@centos5 shell]$ ls test.sh test1.sh >/dev/null 2>&1
#将错误输出2 绑定给 正确输出 1,然后将 正确输出 发送给 /dev/null设备  这种常用

[chengmo@centos5 shell]$ ls test.sh test1.sh &>/dev/null
#& 代表标准输出 ,错误输出 将所有标准输出与错误输出 输入到/dev/null文件

[chengmo@centos5 shell]$ cat>catfile #cat 从test.sh 获得输入数据,然后输出给文件catfile

[chengmo@centos5 shell]$ cat>catfile < test a file
test!
eof
#<< 这个连续两个小符号, 他代表的是『结束的输入字符』的意思。这样当空行输入eof字符,输入自动结束,不用ctrl+D


exec绑定重定向:
实例:
    
[chengmo@centos5 shell]$ exec 6>&1
#将标准输出与fd 6绑定
 
[chengmo@centos5 shell]$ ls  /proc/self/fd/
0  1  2  3  6
#出现文件描述符6
 
[chengmo@centos5 shell]$ exec 1>suc.txt
#将接下来所有命令标准输出,绑定到suc.txt文件(输出到该文件)
 
[chengmo@centos5 shell]$ ls -al
#执行命令,发现什么都不返回了,因为标准输出已经输出到suc.txt文件了
 
[chengmo@centos5 shell]$ exec 1>&6
#恢复标准输出
 
 
[chengmo@centos5 shell]$ exec 6>&-
#关闭fd 6描述符
 
[chengmo@centos5 ~]$ ls /proc/self/fd/
0  1  2  3

说明:使用前先将标准输入保存到文件描述符6,这里说明下,文件描述符默认会打开0,1,2 还可以使用自定义描述符 。然后对标准输出绑定到文件,接下来所有输出都会发生到文件。 使用完后,恢复标准的输出,关闭打开文件描述符6。

exec 3<>test.sh;
#打开test.sh可读写操作,与文件描述符3绑定
 
while read line<&3
 do
    echo $line;
done
#循环读取文件描述符3(读取的是test.sh内容)
exec 3>&-
exec 3<&-

#关闭文件的,输入,输出绑定


ref: http://www.cnblogs.com/chengmo/archive/2010/10/20/1855805.html


你可能感兴趣的:(linux)