[Linux] 文件描述符

来源:http://blog.csdn.net/xlinsist/article/details/51147212

0x00 Linux标准文件描述符

文件描述符 缩写 描述
0 STDIN 标准输入
1 STDOUT 标准输出
2 STDERR 标准错误输出

Linux系统将所有设备都当作文件来处理,而Linux用文件描述符来标识每个文件对象。其实我们可以想象我们电脑的显示器和键盘在Linux系统中都被看作是文件,而它们都有相应的文件描述符与之对应。

其实我们与计算机之间的交互是我可以输入一些指令之后它给我一些输出。
那么我们可以把上面表格中的文件描述符0理解为我和计算机交互时的输入,而这个输入默认是指向键盘的;
文件描述符1理解为我和计算机交互时的输出,而这个输出默认是指向显示器的;
文件描述符2理解为我和计算机交互时,计算机出现错误时的输出,而这个输出默认是和文件描述符1指向一个位置;

0x01 实例体验

既然它们是默认的,我就可以更改它们。下面的命令就是把标准输出的位置改到xlinsist文件中:

exec 1> xlinsist

这回如果我输入ls -al 或者ps命令,我们的终端将不会显示任何东西。现在,我们可以新开一个终端查看xlinsist这个文件中是否有上面两个命令所显示的内容。注意:你必须新开一个终端。

同样的道理,我们也可以改变标准输入的位置。首先,我们先看看没改变的样子:

vincent@geek:~/test$ read user
xlinsist
vincent@geek:~/test$ echo $user
xlinsist
vincent@geek:~/test$

也就是我们从键盘输入把xlinsist读入到user变量。这个read需要我输入。现在,我要改变标准输入的默认位置:

#我只是把当前的标准输出重定向到test文件中
vincent@geek:~/test$ echo 'xlinsist' 1> test
vincent@geek:~/test$ cat test 
xlinsist
#我只是把当前的标准输入重定向到test文件中
vincent@geek:~/test$ read user 0< test 
vincent@geek:~/test$ echo $user
xlinsist
vincent@geek:~/test$ 

从上面的read命令中可以看作,我并没有被要求输入什么。

标准错误输出和标准输出的区别是,它在命令出错情况下的输出。这没有什么太大的不同,我们也可以把它的输出修改到任何我们想要的位置。只不过我们需要把上面标准输出的1改成2,命令如下:

exec 2> xlinsist

当然,除了0, 1,2以外,我们可以分配自己的文件描述符。看下面的例子:

vincent@geek:~/test$ exec 6>test
vincent@geek:~/test$ echo 'i love linux shell!!!' 1>&6
vincent@geek:~/test$ cat test 
i love linux shell!!!

上面的命令很有意思:我首先把文件描述符6指向test文件。因为不像描述符1,所有的输出都会自然找它,然后看它是定向到显示器还是某个文件。所以当我们想找描述符6的时候我们要用&来引用它。其实我们可以把文件描述符想像成一个文件的引用,它可以指向任何一个文件(包括显示器),指向的过程就是我们修改默认位置的过程。而用&符号来找到它指向的目标文件,从而向其写入数据。

如果你真正了解了上面的原理后,我们就可以随便玩什么输入重定向啊、输出重定向啊,那都是小case。现在让我们来个更加复杂的例子吧,来帮你们整理一下思路,脚本如下:

exec 3>&1
exec 1>test
echo "这句话被存到test文件中"
echo "还有这句"
exec 1>&3
echo "这句话输出到显示器"

我们来一步一步理解上面的命令:首先文件描述符1默认指向的是显示器,用&来找到文件描述符1指向的目标文件,也就是显示器。因此文件描述符3也指向了显示器。然后,我们修改了文件描述符1指向的文件到test文件。接着两个echo命令的输出会自然去找文件描述符1,然后它看到文件描述符1指向的是test文件,所以它会把输出写到test文件中。最后,我们用&来找到文件描述符3指向的目标文件,也就是显示器,然后我们修改了文件描述符1指向的文件到显示器。因此,最后一个echo命令会自然的找文件描述符1然后输出到显示器上。

0x02 文件描述符相关的一些shell命令

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

#下面为这个命令的输出
COMMAND   PID    USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash    22609 vincent    0u   CHR 136,13      0t0   16 /dev/pts/13
bash    22609 vincent    1u   CHR 136,13      0t0   16 /dev/pts/13
bash    22609 vincent    2u   CHR 136,13      0t0   16 /dev/pts/13

下图是上面各项的含义


image.png

现在我用下面命令修改其标准错误输出:

vincent@geek:~/test$ exec 1> test 
vincent@geek:~/test$ lsof -a -p $$ -d 0,1,2

#新开一个终端,查看test文件,输出如下
COMMAND   PID    USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
bash    23061 vincent    0u   CHR 136,20      0t0     23 /dev/pts/20
bash    23061 vincent    1w   REG    8,2        0 525789 /home/vincent/test/test
bash    23061 vincent    2u   CHR 136,20      0t0     23 /dev/pts/20
  • /dev/null文件,这是一个很特殊的文件,你写入的任何东西都会清空。大家可以向里面写入数据试试效果。
  1. 我们可以把标准错误输出重定向到/dev/null,从而丢掉不想保存的错误信息
  2. 我们可以快速移除现有文件的数据而不用先删除文件在创建。命令如下:
cat /dev/null > test
  • Linux使用/tmp目录来存放不需要一直保留的文件,大多数Linux系统会在启动时自动删除/tmp目录中所有的文件。

下面的命令可供使用:

# 文档说文件的末尾必须至少包含3个'X',这个是在当前目录创建的
mktemp test.XXX
# 这个是在/tmp目录创建的
mktemp -t test.XXXXX
# 创建目录,在当前目录
mktemp -d test.XXXXX
  • tee命令 – 从标准输入读取,写到标准输出和文件。
# 把date产生的输出写到标准输出和文件
date | tee test
# 追加数据
date | tee -a test

0x03 管道和重定向之间的区别

管道是把一个程序的输出作为另一个程序的输入。 重定向是把输出定向到文件或者标准流。
这有2个非常详细的参考资料:
1、http://askubuntu.com/questions/172982/what-is-the-difference-between-redirection-and-pipe
2、http://ryanstutorials.net/linuxtutorial/piping.php
最好是先看第二个链接

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容