linux shell 文件描述符和重定向

@什么是文件描述符
@有关《linux命令行与脚本编程大全》中提到的单进程文件描述符限制问题
@文件描述符和文件名重定向中使用区别

什么是文件描述符

文件描述符是一个整数,代表一个文件,每个进程自动打开3个文件:stdin,stdout,stderr。目前我的电脑上每个进程可以打开的文件描述符是1024个(通过“ulimit -n”命令查询)。

有关《linux命令行与脚本编程大全》中提到的单进程文件描述符限制问题

该书中描述到一个进程一个最多可以有9个文件描述符的说法,我很是困惑。linux中万物皆是文件,9个肯定是远远不够的。难道一个linux中一个进程只能打开6个文件(0,1,2已经被进程预留),之前一直以为是作者笔误。
是否有另外一种可能呢,文件描述符只有9个,分别为[0-8]。但打开的文件有1024个限制,但我在Ubuntu1804上使用exec 9>testout是没有问题的。文件描述符一直到1023都是没有问题的。但1024的时候,系统提示文件描述符错误。由此可见,原文中这个说法要么是错误,要么是过时了。

文件描述符和文件名重定向中使用区别

文件描述符缩写描述含义
0STDIN标准输入键盘
1STDOUT标准输出显示屏
2STDERR标准错误显示屏

当你在文件中新创建一个新文件时,它的文件标志符会从3开始顺延下去。

bash命令重定向

缺省我们bash命令输出都是使用显示器,也就是文件描述符为1的那个文件,如果我们想将bash命令输出到其它文件,比如output.txt。那我们只需简单只用重定向符号’>'。
ls -al > output.txt
文件可以自动创建,每次都是从文件开头开始写。在文件中追加输出的话我们可以使用符号">>"。
这里有2个问题要注意下:

  • 隐含的文件描述符:这里实际上命令可以看做ls -al 1> output.txt 这里的’>'前面的1就是标准输出的文件描述符。如果我们我们要将标准错误重定向,就是llls -al 2> output.txt。(这里没有llls命令,故会出错)这里我们先假设一个重要结论,'>'左边用文件描述符,右边用文件名。
  • 文件名在脚本中的使用:单独执行一条命令我们可以简单的使用这种方法进行重定向。但如果一个脚本中所有的语句我们都要重定向的话,未免有些麻烦。

脚本中重定向-临时

假设你的脚本中有信息需要写标准错误文件而不是输出到屏幕上,你可以这么做。

#!/bin/bash
#文件名为redirect.sh
if [ something happen ]
echo "这句话输出到标准错误文件" >&2
fi

这样你在执行这个脚本(redirect.sh)的时候只需./redirect.sh 2>output.txt便可将这些你要输出的信息写入output.txt文件,而不是出现在屏幕上。当然,你说费那个事干嘛?

echo "这句话输出到标准错误文件" > output.txt

也不是不行的,只不过后面还要改成追加符’>>‘,同时每次还要比’&2’多敲8个字符么。更重要的是在()中的执行的语句这种方法是无法达成目标的。
这里同样有2个问题要注意:

  • 重定向符’>‘和’&2’和之间没有空格,这个是和前面bash命令中不一样。bash脚本就是这个空格的使用比较诡异。
  • 重定向符’>‘的右边我们说应该是文件名,这里是’&2’,可以理解为bash中的文件描述符是个地址,'&2’可以找到文件名(不能用stderr)。也符合我们前面假设。

脚本重定向-永久

前面那个例子中,我们还要在脚本执行的时候使用重定向,才能将相关信息输出到output文件中,我们能否在脚本中设定呢,但这样操作之后,想改回std输出比较难了。

#!/bin/bash
exec 2> output.txt
if [ something happen ]
echo "这句话输出到标准错误文件" >&2
fi

为啥改回比较难了呢?我们直接执行
exec output.txt>&2行不行呢?答案是不行。我们前面的结论是’>'左边是文件描述符,可是我们无法获得output.txt的文件描述符。学艺不精,我是网上搜索了下,没找到方法。

如果我们非要在永久重定向之后回复标准输出,虽然我没有想明白为什么,但我们可以通过中间文件描述符搞定。

 exec 8>&1
 exec 1> output.txt
 echo "你想保留在output.txt中的信息"
 exec 1>&8
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值