`

linux文件描述符-标准输入输出

阅读更多

当某个进程打开文件时,操作系统返回相应的文件描述符,进程为了处理该文件必须引用此描述符。

所谓的文件描述符是一个低级的正整数。最前面的三个文件描述符(0,1,2)分别与标准输入(stdin),标准输出(stdout)和标准错误(stderr)对应。

因此,函数 scanf() 使用 stdin,而函数 printf() 使用 stdout。你可以用不同的文件描述符改写默认的设置并重定向进程的 I/O 到不同的文件。

 

标准输入与输出

执行一个shell命令行时通常会自动打开三个标准文件,即标准输入文件(stdin),通常对应终端的键盘;

标准输出文件(stdout)和标准错误输出文件(stderr),这两个文件都对应终端的屏幕。

进程将从标准输入文件中得到输入数据,将正常输出数据输出到标准输出文件,而将错误信息送到标准错误文件中。

以cat命令为例,cat命令的功能是从命令行给出的文件中读取数据,并将这些数据直接送到标准输出。

若使用如下命令:

$ cat config

将会把文件config的内容依次显示到屏幕上。但是,如果cat的命令行中没有参数,它就会从标准输入中读取数据,并将其送到标准输出。例如:

$ cat

Hello world

Hello world

用户输入的每一行都立刻被cat命令输出到屏幕上。

 

直接使用标准输入/输出文件存在以下问题:

输入数据从终端输入时,用户费了半天劲输入的数据只能用一次。下次再想用这些数据时就得重新输入。而且在终端上输入时,若输入有误修改起来不是很方便。

输出到终端屏幕上的信息只能看不能动。无法对此输出作更多处理,如将输出作为另一命令的输入进行进一步的处理等。

为了解决上述问题,Linux系统为输入、输出的传送引入了另外两种机制,即输入/输出重定向和管道

 

输入重定向

输入重定向是指把命令(或可执行程序)的标准输入重定向到指定的文件中。也就是说,输入可以不来自键盘,而来自一个指定的文件。

所以说,输入重定向主要用于改变一个命令的输入源,特别是改变那些需要大量输入的输入源。

例如,命令wc统计指定文件包含的行数、单词数和字符数。如果仅在命令行上键入:

$ wc

wc将等待用户告诉它统计什么,这时shell就好象死了一样,从键盘键入的所有文本都出现在屏幕上,但并没有什么结果,直至按下ctrl+d,wc才将命令结果写在屏幕上。

如果给出一个文件名作为wc命令的参数,如下例所示,wc将返回该文件所包含的行数、单词数和字符数。

$ wc /etc/passwd

20 23 726 /etc/passwd

另一种把/etc/passwd文件内容传给wc命令的方法是重定向wc的输入。输入重定向的一般形式为:命令<文件名。可以用下面的命令把wc命令的输入重定向为/etc/passwd文件:

$ wc < /etc/passwd

20 23 726

 

输出重定向

输出重定向是指把命令(或可执行程序)的标准输出或标准错误输出重新定向到指定文件中。这样,该命令的输出就不显示在屏幕上,而是写入到指定文件中。

输出重定向比输入重定向更常用,很多情况下都可以使用这种功能。

例如,如果某个命令的输出很多,在屏幕上不能完全显示,那么将输出重定向到一个文件中,然后再用文本编辑器打开这个文件,就可以查看输出信息;如果想保存一个命令的输出,也可以使用这种方法。

还有,输出重定向可以用于把一个命令的输出当作另一个命令的输入(还有一种更简单的方法,就是使用管道,将在下面介绍)。

输出重定向的一般形式为:命令>文件名。例如:

$ ls > directory.out

$ cat directory.out

ch1.doc ch2.doc ch3.doc chimp config mail/ test/

将ls命令的输出保存为一个名为directory.out的文件。

注:如果>符号后边的文件已存在,那么这个文件将被重写。

为避免输出重定向中指定文件只能存放当前命令的输出重定向的内容,shell提供了输出重定向的一种追加手段。

输出追加重定向与输出重定向的功能非常相似,区别仅在于输出追加重定向的功能是把命令(或可执行程序)的输出结果追加到指定文件的最后,而该文件原有内容不被破坏。

如果要将一条命令的输出结果追加到指定文件的后面,可以使用追加重定向操作符>>

形式为:命令>>文件名。例如:

$ ls *.doc>>directory.out

$ cat directory.out

ch1.doc ch2.doc ch3.doc chimp config mail/ test/

ch1.doc ch2.doc ch3.doc

和程序的标准输出重定向一样,程序的错误输出也可以重新定向。2>(或2>>)表示对错误输出设备重定向。例如下面的命令:

$ ls /usr/tmp 2> err.file

可在屏幕上看到程序的正常输出结果,但又将程序的任何错误信息送到文件err.file中,以备将来检查用。

还可以使用另一个输出重定向操作符(&>)将标准输出和错误输出同时送到同一文件中。例如:

$ ls /usr/tmp &> output.file

利用重定向将命令组合在一起,可实现系统单个命令不能提供的新功能。例如使用下面的命令序列:

$ ls /usr/bin > /tmp/dir

$ wc -w < /tmp/dir

459

统计了/usr/bin目录下的文件个数。

 

管道

将一个程序或命令的输出作为另一个程序或命令的输入,有两种方法,

一种是通过一个临时文件将两个命令或程序结合在一起,例如上个例子中的/tmp/dir文件将ls和wc命令联在一起;

另一种是Linux所提供的管道功能。这种方法比前一种方法更好。

管道可以把一系列命令连接起来,这意味着第一个命令的输出会作为第二个命令的输入通过管道传给第二个命令,第二个命令的输出又会作为第三个命令的输入,以此类推。

显示在屏幕上的是管道行中最后一个命令的输出(如果命令行中未使用输出重定向)。

通过使用管道符“|”来建立一个管道行。用管道重写上面的例子:

$ ls /usr/bin|wc -w

1789

 

命令替换

命令替换和重定向有些相似,但区别在于命令替换是将一个命令的输出作为另外一个命令的参数。常用命令格式为:

command1 `command2`

其中,command2的输出将作为command1的参数。需要注意的是这里的`符号,被它括起来的内容将作为命令执行,执行后的结果作为command1的参数。例如:

$ cd `pwd`

该命令将pwd命令列出的目录作为cd命令的参数,结果仍然是停留在当前目录下

 

首先说什么是文件描述符,它有什么作用?

文件描述符是一个简单的整数,用以标明每一个被进程所打开的文件和socket。第一个打开的文件是0,第二个是1,依此类推。

Unix 操作系统通常给每个进程能打开的文件数量强加一个限制。更甚的是,unix 通常有一个系统级的限制。

例如:squid 的工作方式,文件描述符的限制可能会极大的影响性能。当squid 用完所有的文件描述符后,它不能接收用户新的连接。

也就是说,用完文件描述符导致拒绝服务。squid 不能接收新请求,直到一部分当前请求完成,相应的文件和socket 被关闭。当squid发现文件描述符短缺时,它会发布警告。

在运行./configure 之前,检查你的系统的文件描述符限制是否合适,能给你避免一些麻烦。

大多数情况下,1024 个文件描述符足够了。非常忙的cache可能需要4096或更多。在配置文件描述符限制时,我推荐设置系统级限制的数量为每个进程限制的2 倍。

 

2、怎么突破,具体方法?

先查看Linux默认的文件描述符:

# ulimit -n

1024

我们用命令ulimit -HSn 65536来增大文件描述符,然后编译安装squid,把ulimit -HSn 65536放到/etc/rc.d/rc.local让启动时加载。

 

在Linux下面部署web应用的时候,有时候会遇上Socket/File: Can’t open so many files的问题;

这个值也会影响服务器的最大并发数,其实Linux是有文件句柄限制的,而且Linux默认不是很高,一般都是1024,生产服务器用其实很容易就达到这个数量。

 

查看方法

我们可以用ulimit -a来查看所有限制值

[root@centos5 ~]# ulimit -a

core file size          (blocks, -c) 0

data seg size           (kbytes, -d) unlimited

max nice                        (-e) 0

file size               (blocks, -f) unlimited

pending signals                 (-i) 4096

max locked memory       (kbytes, -l) 32

max memory size         (kbytes, -m) unlimited

open files                      (-n) 1024

pipe size            (512 bytes, -p) 8

POSIX message queues     (bytes, -q) 819200

max rt priority                 (-r) 0

stack size              (kbytes, -s) 10240

cpu time               (seconds, -t) unlimited

max user processes              (-u) 4096

virtual memory          (kbytes, -v) unlimited

file locks                      (-x) unlimited||<

 

其中 "open files (-n) 1024 "是Linux操作系统对一个进程打开的文件句柄数量的限制(也包含打开的SOCKET数量,可影响MySQL的并发连接数目)。

这个值可用ulimit命令来修改,但ulimit命令修改的数值只对当前登录用户的目前使用环境有效,系统重启或者用户退出后就会失效。

(在布署Nginx+FastCGI我就遇到这个问题,将ulimit -SHn 65535放到/etc/rc.d/rc.local也没起什么作用)

系统总限制是在这里,/proc/sys/fs/file-max。可以通过cat查看目前的值,修改/etc/sysctl.conf 中也可以控制。

另外还有一个,/proc/sys/fs/file-nr,可以看到整个系统目前使用的文件句柄数量。

 

查找文件句柄问题的时候,还有一个很实用的程序lsof。可以很方便看到某个进程开了那些句柄,也可以看到某个文件/目录被什么进程占用了。

 

修改方法

若要令修改ulimits的数值永久生效,则必须修改配置文档,可以给ulimit修改命令放入/etc/profile里面,这个方法实在是不方便,还有一个方法是修改/etc/sysctl.conf。

我修改了,测试过,但对用户的ulimits -a 是不会改变的,只是/proc/sys/fs/file-max的值变了。

 

我认为正确的做法,应该是修改/etc/security/limits.conf,里面有很详细的注释,比如

* soft   nofile 32768

* hard nofile 65536

就可以将文件句柄限制统一改成软32768,硬65536。配置文件最前面的是指domain,设置为星号代表全局,另外你也可以针对不同的用户做出不同的限制。

 

注意:这个当中的硬限制是实际的限制,而软限制,是warnning限制,只会做出warning;其实ulimit命令本身就有分软硬设置,加-H就是硬,加-S就是软

默认显示的是软限制,如果运行ulimit命令修改的时候没有加上的话,就是两个参数一起改变。

 

分享到:
评论

相关推荐

    LINUX输入输出与文件

    LINUX输入输出与文件 1 1. 基于文件指针的文件操作(缓冲) 1 1.1. 文件的创建,打开与关闭 1 1.2. 读写文件 2 1.3. 标准输入/输出流 5 2. 基于文件描述符的文件操作(非缓冲) 6 2.1. 文件描述符 6 2.2. 打开、创建和...

    Linux输入输出重定向详细使用说明

    文件描述符 类型 符号表示 键盘 /dev/stdin 0(缺省是键盘,为0时是文件或者其他命令的输出) 标准输入 &lt; &lt;&lt; 显示器 /dev/stdout 1(缺省是屏幕,为1时是文件) 标准输出 &gt; &gt;&gt; 显示器 /dev/stderr 2...

    linux网络编程-宋敬彬-part3

    3.2.1 文件描述符 72 3.2.2 打开创建文件open()、create()函数 72 3.2.3 关闭文件close()函数 76 3.2.4 读取文件read()函数 77 3.2.5 写文件write()函数 79 3.2.6 文件偏移lseek()函数 80 3.2.7 获得...

    linux网络编程-宋敬彬-part2

    3.2.1 文件描述符 72 3.2.2 打开创建文件open()、create()函数 72 3.2.3 关闭文件close()函数 76 3.2.4 读取文件read()函数 77 3.2.5 写文件write()函数 79 3.2.6 文件偏移lseek()函数 80 3.2.7 获得...

    Linux base shell重定向详解

    在linux shell执行命令时,每个进程都和三个打开的文件相联系,并使用文件描述符来引用这些文件。由于文件描述符不容易记忆,shell同时也给出了相应的文件名: 文件 文件描述符 输入文件—标准输入 0(缺省是...

    测试云服务,上传css文档

    习惯上,标准输入(standard input)的文件描述符是 0,标准输出(standard output)是 1,标准错误(standard error)是 2。尽管这种习惯并非Unix内核的特性,但是因为一些 shell 和很多应用程序都使用这种习惯,...

    Linux2.6内核标准教程(共计8-- 第1个)

    5.3.1 中断描述符表的初步初始化 204 5.3.2 中断描述符表的最终初始化 206 5.4 具体处理过程 216 5.4.1 公用的硬件处理阶段 217 5.4.2 中断的软件处理阶段 218 5.4.3 异常的软件处理阶段 229 5.5 延迟...

    Linux2.6内核标准教程(共计8--第6个)

    5.3.1 中断描述符表的初步初始化 204 5.3.2 中断描述符表的最终初始化 206 5.4 具体处理过程 216 5.4.1 公用的硬件处理阶段 217 5.4.2 中断的软件处理阶段 218 5.4.3 异常的软件处理阶段 229 5.5 延迟...

    Linux2.6内核标准教程(共计8--第8个)

    5.3.1 中断描述符表的初步初始化 204 5.3.2 中断描述符表的最终初始化 206 5.4 具体处理过程 216 5.4.1 公用的硬件处理阶段 217 5.4.2 中断的软件处理阶段 218 5.4.3 异常的软件处理阶段 229 5.5 延迟...

    linux网络编程-宋敬彬-part1

    8.3.1 进行文件描述符判定的函数issockettype() 224 8.3.2 main()函数 224 8.4 IP地址与域名之间的相互转换 225 8.4.1 DNS原理 225 8.4.2 获取主机信息的函数 226 8.4.3 使用主机名获取主机信息的例子 228...

    Linux2.6内核标准教程(共计8--第3个)

    5.3.1 中断描述符表的初步初始化 204 5.3.2 中断描述符表的最终初始化 206 5.4 具体处理过程 216 5.4.1 公用的硬件处理阶段 217 5.4.2 中断的软件处理阶段 218 5.4.3 异常的软件处理阶段 229 5.5 延迟...

    Linux2.6内核标准教程(共计8--第7个)

    5.3.1 中断描述符表的初步初始化 204 5.3.2 中断描述符表的最终初始化 206 5.4 具体处理过程 216 5.4.1 公用的硬件处理阶段 217 5.4.2 中断的软件处理阶段 218 5.4.3 异常的软件处理阶段 229 5.5 延迟...

    linux操作系统课程设计完善代码

    当任何进程开始时,它的文件描述符0和1必须是指向标准输入和标准输出。使用UserKernel.console.openForReading()和UserKernel.console.openForWriting()会很容易做到这点。用户进程可以关闭这些描述符,就像通过open...

    输入输出重定向

    文件描述符 标准输出 0 标准输入 1 标准错误 2 对于输入重定向来讲,用到的符号及其作用如下表所示: 符号 作用 命令1 &gt; 文件 将标准输出重定向到一个文件中 命令 2&gt; 文件 将错误输出重定向...

    深入理解Linux shell中2&1的含义(全网最全,看完就懂)

    在Linux系统中0 1 2是一个文件描述符 名称 代码 操作符 Java中表示 Linux 下文件描述符(Debian 为例) 标准输入(stdin) 0 &lt; 或 &lt;&lt; System.in /dev/stdin -&gt; /proc/self/fd/0 -&gt; /dev/pts/0 标准...

    Linux的常用命令cat、sed、zip等用法,以及shell编程的基本语法,以及makefile编写方式等等

    3.lvim工作方式、gcc、gdb用法、动态库和静态库的制作与使用、makefile的编写语法,以及makefile里面的模式匹配、函数、伪目标等知识,以及文件描述符、文件操作(open、close、lseek、stat、dup等语法) 3.进程:进程...

    Linux基础命令学习——重定向与管道符(五)

    标准输入重定向:stdin,文件描述符为0,默认从键盘输入; 标准输出重定向:stdout,文件描述符为1,默认输出到屏幕; 错误输出重定向:stderr,文件描述符为2,默认输出到屏幕; 输入重定向 1、使用重定向命令把...

    入门学习Linux常用必会60个命令实例详解doc/txt

    不过目前大多数较新的Linux发行版本(包括红旗 Linux、中软Linux、Mandrake Linux等)都可以自动挂装文件系统,但Red Hat Linux除外。 umount 1.作用 umount命令的作用是卸载一个文件系统,它的使用权限是超级...

Global site tag (gtag.js) - Google Analytics