linux文件内容操作命令,linux的文件常用命令及其操作
使用文件
在这一部分,我们将讨论Linux文件和目录以及如何管理它们。我们将学习如何创建文件、打开文件、读取文件、写入文件和关闭文件。我们还将学习程序如何管理目录(如创建、扫描和删除)。在上一部分中,我们使用Shell进行编程,但现在我们将开始使用C编程。
在讨论Linux如何处理文件I/O之前,我们将了解一些与文件、目录和设备相关的概念。要处理文件和目录,我们需要使用系统调用(Unix/Linux调用类似于Windows API),但是也有一系列的库函数,标准I/O库(stdio),让我们的文件处理更加有效。
在这里,我们将讨论处理文件和目录的各种调用,因此我们将讨论以下内容:
1文件和设备
2系统调用
3库函数
4低级文件访问
5文件管理
6标准输入输出库
7格式输入和输出
8文件和目录维护
9目录扫描
10错误
11 /proc文件系统
12个高级主题:fcntl和mmap
Linux文件
有人可能会问:为什么?我们讨论一下文件结构好吗?这一点我们已经知道了。是的,与Unix类似,文件在Linux中非常重要,因为它们提供了一个简单一致的接口来处理系统服务和设备。在Linux中,一切都是文件。
这意味着在Linux中,程序可以像普通文件一样使用磁盘文件、串口、打印机等设备。
目录也是一种特殊的文件。在现代的Unix版本中,包括Linux,即使是超级用户也不能直接写它们。所有普通用户在不了解目录实现的系统细节的情况下,使用高级opendir/readdir接口读取目录。我们将在后面讨论特殊的目录函数。
的确,在Linux下,所有内容都被视为文件,或者可以通过特殊文件访问。即便如此,还是有一些主要的原则,和我们平时所了解和喜欢的文件是不一样的。现在让我们来看看我们谈到的特殊情况。
目录
像它的内容一样,一个文件有一个文件名和一些属性,或者管理信息;也就是说,这些文件的创建/修改日期和访问权限。这些属性存储在文件的inode中。所谓inode,就是文件系统中一个特殊的数据块,它包含了文件的长度、在磁盘上的存储位置等信息。系统使用文件的索引节点数量,目录结构只是为了方便我们命名文件。
目录是包含索引节点数量和其他文件名的文件。每个目录实体都是一个指向文件索引节点的链接。如果这个文件名被删除,我们也将删除这个链接(我们可以使用ls -i命令来检查一个文件的inodes的数量)。使用ln命令,我们可以在不同的目录中创建指向同一个文件的链接。如果链接到一个文件的数量(即ls -l命令输出中许可后的数量)
文件排列在目录中,其中一些可能有子目录。这就形成了我们熟悉的文件系统结构。一个名为neil的用户通常将他的文件存储在主目录中,可能是/home/neil,也可能有一些子目录如e-mail。这里要注意的是,Unix和Linux Shell中都有一个命令直接到达我们用户的主目录,那就是~。如果要输入其他用户的目录,我们可以输入~user。我们知道,每个用户的主目录都是因为这个特殊原因而创建的高级目录的子目录,这里是/home。
这里,我们应该注意标准库函数不支持filename参数的~符号。
/home目录只是根目录/的子目录,根目录是文件系统层次结构的最高级别,包含其子目录中的所有系统文件。根目录通常包含系统程序的/bin目录和系统配置文件的/etc目录。库的/lib目录。代表物理设备并为处理这些设备提供接口的文件位于/dev目录中。我们可以在Linux文件系统Stander上找到更详细的内容,也可以使用man hier命令获得更详细的描述。
文件和设备
甚至硬件设备也表示为文件。例如,作为超级用户,我们可以将CD-ROM作为文件挂载:
# mount-t iso 9660/dev/hdc/mnt/cdrom
# cd /mnt/cdrom
这将启动CD-ROM设备,并将其内容分支为/mnt/cdrom文件结构。我们可以像普通文件一样进入光盘目录,当然这些内容是只读的。
Unix和Linux中常见的三个最重要的设备是/dev/console、/dev/tty和/dev/null。
/dev/控制台
这个设备代表系统控制台。经常向该设备发送错误和判断消息。每个Unix系统都有一个指定的终端或屏幕来接收控制台消息。曾经,这是一个复杂的打印终端。在现代工作站或Linux中,它通常是一个活动的虚拟控制台,而在X中,它将是屏幕上的一个特殊控制窗口。
/dev/tty
/dev/tty是过程控制终端的别名。如果有这样的进程,比如cron运行的进程就不会有控制终端,所以他不会打开/dev/tty。
在可以使用的地方,/dev/tty允许程序直接向用户写入信息,而不管用户使用的是哪种终端。它在标准输出重定向中非常有用。ls -R more命令就是一个例子,在这里,more可以向用户提示输出的每一个新页面。
这里要注意的是,虽然只有一个/dev/console设备,但是可以通过/dev/tty访问很多不同的物理设备。
/dev/null
这是一个空设备。写入该设备的所有信息都将被丢弃。当读取这个文件时,它将立即到达文件的末尾,以便可以使用cp命令将它用作空文件源。所有不需要的输出都可以重定向到该设备。
创建新文件的另一种方法是使用touch filename命令,该命令将修改文件的修改日期。如果该文件不存在,将会创建它。但是,它不会清空其内容。
$ echo不想看到这个/dev/null
$ cp /dev/null空文件
可以在/dev目录中找到的其他设备有硬盘、软盘、通信端口、磁带、CD-ROM、声卡和一些代表系统内部状态的设备。还有一个设备/dev/zero。它可以用作空字节的来源,以创建零文件大小的文件。我们需要超级用户的许可来访问一些设置。普通用户无法使用程序直接访问像硬盘这样的低级设备。设备名称可能因系统而异。在Linux发行版中,通常有一个程序需要超级用户运行来管理这些设备文件,比如mount命令。
设备可以分为字符设备和块设备。不同之处在于,一些设备需要一次访问一个块。块设备通常是指那些支持随机访问的文件系统,比如硬盘。
系统调用和设备驱动程序
我们可以使用一些函数来访问和控制设备文件。这些函数称为系统调用,是Unix/Linux直接提供给操作系统的接口。
在操作系统的核心,内核是大量的设备驱动程序。这是控制系统硬件的低级接口的集合。例如,将有一个磁带驱动程序,它可以知道如何启动磁带,向前或向后,读取或写入。他也知道磁带每次都要写入一定大小的数据块。因为磁带是顺序访问的,所以驱动程序不能直接访问磁带块,必须到指定的位置。
同样,低级硬盘设备每次都会写入指定的磁盘块,但是可以直接访问所需的磁盘块,因为磁盘是随机访问设备。
为了提供类似的接口,硬盘驱动器封装了所有硬件相关的功能。硬件的材质特性可以通过ioctl获得。
/dev中的设备文件也可以以同样的方式使用。它们可以被打开、读取、写入和关闭。例如,用于打开常规文件的open调用可用于访问用户终端、打印机或磁带。
用于访问设备驱动程序的生成系统调用包括:
1:打开文件或设备。
2:从打开的文件或设备中读取。
3:写一个文件或设备。
4关闭:关闭文件或设备。
Ioctl:将控制信息传输到设备驱动程序
Ioctl系统调用用于提供必要的硬件控制,所以会因设备而异。例如,ioctl调用可以用来重新定位磁带或设置串行端口的字符流。因此,没有必要将ioctl从一台机器移植到另一台机器。其他每个驱动程序都定义了自己的ioctl命令集。
内置函数
直接低级系统输入和输出的问题是这种方法不是很有效。为什么?
1使用系统调用会产生不好的结果。与函数调用相比,系统调用浪费了大量的资源,因为Linux要在执行我们的程序代码和执行它的内核代码之间切换。好的办法是在一个程序中尽可能少的使用系统,同时让每个系统调用做尽可能多的工作,比如每次读或写很多数据,而不是第一次只读写一个字符。
2由于硬件的限制,每次使用底层系统调用所能读写的数据大小有很多限制。例如,对于磁带机,它们每次可以写入的数据块大小是10k。因此,如果我们每次要写入的数据块的大小不是10k的整数倍,那么磁带将向前移动到下一个10k,在磁带上留下一个空白。
为了给设备或硬盘文件提供一个高级接口,类似于Unix,Linux发行版提供了大量的标准库。这是一个函数的集合,我们可以把它包含在我们的程序中来处理这些问题。一个很好的例子是提供缓冲输出的标准I/O库。我们可以高效地编写可变大小的数据块,这样我们就可以使用低级别的系统调用来提供完整的数据块。这将大大减少系统调用的开销。
库通常位于手册页的第三部分,与之相对的通常还有一个标准头文件,比如标准输入输出的stdio.h。
低级文件访问
每个正在运行的程序,称为进程,都有一系列与之对应的文件描述符。这些是一些小整数,我们可以用它们来访问打开的文件或设备。我们可以使用多少这些紧急描述符取决于我们的系统配置。当一个程序启动时,它通常有三个开放的描述符。它们是:
0:标准输入
1:标准输出
2:标准误差输出
我们可以使用开放系统调用来使用其他文件或设备的描述符,这正是我们将在后面讨论的内容。但是,那些自动打开的文件描述符可以让我们使用write创建一些简单的程序。
写
系统会将buf中第一个nbytes字节的内容写入与fildes文件描述符相关的文件。他的返回值是实际写入的字节数。如果文件描述符中有错误,或者底层设备驱动程序需要块大小,则返回值可能小于nbytes。如果函数返回0,则意味着没有写入数据。如果函数返回-1,说明写调用有错误,这个错误会存储在errno全局变量中。
write的语法如下:
#包括unistd.h
size_t write(int fildes,const void *buf,size _ t nbytes);
有了这些知识,我们可以编写我们的第一个程序,simple_write.c:
#包括unistd.h
#包含stdlib.h
int main()
{
如果((写(1,“这里有些数据/n”,18))!=18)
write(2,“文件描述符1/n发生写入错误”,46);
退出(0);
}
这个程序只是在标准输出上打印一条消息。当程序结束时,所有打开的描述符都会自动关闭,所以我们不需要关闭它们。然而,当我们处理缓冲区的输出时,情况并非如此。
运行这个程序,我们将得到以下输出:
$简单_写
这是一些数据
$
这里值得注意的是,可能有消息说他写的字节数比我们要求的要少。这不是必要的错误。在我们的程序中,我们需要松果来检查错误以检测错误,并调用write来写入剩余的数据。
阅读
read系统调用将从fildes文件描述符指示的文件中读取nbytes字节的数据,并将读取的数据放入数据区buf。他的返回值是实际读取的字节数,可能比要求的值小。如果read函数返回0,则它没有读取任何内容,而是到达了文件的末尾。同样,如果出现错误,它将返回-1。
其语法如下:
#包括unistd.h
size_t read(int fildes,void *buf,size _ t nbytes);
下面的简单程序simple_read.c将从标准输入到标准输出读取128个字符。如果数据的实际数量少于128,它将读取所有内容。
#包括unistd.h
#包含stdlib.h
int main()
{
充电缓冲器[128];
int nread
nread=read(0,buffer,128);
if (nread==-1)
write(2,“发生了读取错误/n”,26);
if ((write(1,buffer,nread))!=nread)
write(2,“发生了写入错误/n”,27);
退出(0);
}
如果我们运行这个程序,我们将得到以下输出:
$ echo你好简单_阅读
大家好
$ simple_read draft1.txt
文件
在这一章中,我们将会看到文件和目录以及如何操作它们
他们。我们将学习如何创建文件
在第一次运行中,我们使用echo命令为程序创建一些输入,这些输入将被导入到程序中。在第二次运行中,我们从一个文件中重定向输入。在这种情况下,我们发现文件draft1.txt的第一部分出现在标准输出中。
打开
为了创建一个新的文件描述符,我们需要使用open系统调用。其语法格式如下:
#包含fcntl.h
#包含sys/types.h
#包含系统/统计信息
int open(const char *path,int of lags);
int open(const char *path,int oflags,mode _ t mode);
严格来说,我们打开一个POSIX系统不需要包含sys/types.h和sys/stat.h,但是在某些Linux系统中是必须的。
简而言之,open建立了文件或设备的访问路径。如果调用成功,它将返回一个文件描述符,该描述符可用于读、写或其他系统调用。此文件描述符是唯一的,不会与其他正在运行的进程共享。如果两个程序同时打开同一个,它们将分别维护不同的文件描述符。如果他们同时写文件,他们会在读取文件的地方写文件。这些数据不会被插入,但一个会覆盖另一个。每个程序都会记录它们所读写的文件的偏移量信息。我们可以通过使用文件锁定来避免这种情况。
要打开的文件或设备的名称作为path参数传入,而oflags参数指定要对打开的文件执行的操作。
Oflags是通过强制文件访问或其他可选模式的某种组合来指定的。open调用必须指定以下文件访问模式之一:
O _ RDONLY以只读方式打开。
O_WRONLY以只写模式打开。
O_RDWR是开放读写的。
此调用还可以在oflags参数中包含以下可选模式的组合(使用或):
O_APPEND在文件末尾写入数据。
O_TRUNC将文件大小设置为零,而不考虑现有的内容。
O_CREAT如果需要,在指定模式下创建一个文件。
O_EXCL与O_CREAT一起使用,以确保文件是通过调用。
Open是原子的,也就是说,它只是作为一个函数被调用。该项目禁止两个程序同时创建文件。如果文件已经存在,打开将失败。
oflags的其他可能参数可以在打开的手册页中找到,该手册页可以在手册页的第二部分中找到(使用man 2 open)。
如果open调用成功,将返回一个新的文件描述符(通常为非负整数),如果失败,将返回-1。同时,open将设置errno全局变量来指示失败的原因。我们将在后面的部分详细讨论errno。新的文件描述符总是最小的未使用的文件描述符,这在某些情况下非常有用。例如,如果一个程序关闭它的标准输出,然后调用open函数,文件描述符1可以被重用,标准输出可以被有效地重定向到另一个不同的文件或设备。还有一个由POSIX标准化的creat调用,但这个函数并不常用。creat并不只是像我们希望的那样创建一个文件,而是会同时打开它,这就用到了O _ CREAT O _ WRONLY O _
初始权限
当我们使用open函数的O_CREAT创建一个文件时,我们必须使用第三个参数的形式。mode是第三个参数,在文件sys/stat中定义。这些权限如下:
S_IRUSR:所有者读取权限
S_IWUSR:所有者写权限
S_IXUSR:所有者的执行权
S_IRGRP:组读取权限
S_IWGRP:组写权限
S_IXGRP:组执行权限
S_IROTH:其他用户的读取权限
其他用户的写权限
S_IXOTH:其他用户的执行权限
例如,下面的例子:
open ("myfile ",O_CREAT,S _ I rusr S _ IXOTH);
这个例子将生成一个名为myfile的文件,它的权限是所有者的读取权限和其他用户的执行权限,并且只有这些权限。
$ ls -ls我的文件
0 -r - x 1 neil软件0 9月22日08:11 myfile*
有许多因素会影响文件的权限。首先,只有创建文件时使用的权限。第二,用户的掩码位(由umask命令指定)影响创建的文件权限。调用open时指定的模式值,并在运行时保留用户掩码位。例如,如果用户的掩码位设置为001,并且在创建文件时指定了S_IXOTH权限,那么创建的文件将不会有其他用户的执行权限,因为用户的掩码位不提供其他用户的执行权限。事实上,open和creat调用中的标志需要请求权限设置。是否设置请求的权限取决于运行时的umask值。
默认属性
Umask是一个系统变量,可用于在创建文件时设置文件权限的掩码位。我们可以通过执行umask命令并提供一个新值来更改这个变量的值。umask的值是一个三位十六进制数。每个数字都是1、2或4中的数字相加的结果。我们可以从下表中清楚地理解这个意思。每个不同的数字可以对应于用户、组。
第一:
禁止任何用户对0的权限。
4禁止用户的读取权限。
2禁止用户写权限。
1用户的执行权限被禁止。
第二名:
不禁止0的任何组权限。
4禁止组读取权限。
2禁止组写权限。
1禁止组执行权限。
第三名:
不禁止其他用户的0权限。
4禁止其他用户的读取权限。
禁止其他用户的写权限。
1禁止其他用户的执行权限。
例如,要禁用group的写和执行权限以及other的写权限,我们可以使用以下umask值:
数字值
1 0
2 2
一个
3 2
每一位的值都是相加的结果,所以第二位会是2 ^ 1,也就是3。所以umask值将是032。
当我们使用open或creat创建一个文件时,mode参数将与umask值进行比较。模式参数和umask值中设置的位将被删除。最终的结果将是用户可以设置自己的环境:不要用其他用户的写权限创建文件,只有创建文件的程序才需要这样的权限设置。这并不会阻止某个程序或用户在以后使用chmod命令(或在某个程序中使用chmod系统调用)来增加其他用户的写权限,但确实可以防止用户对所有新文件进行检查和设置权限,从而保护用户。
关闭
我们使用close系统调用来关闭文件描述符、文件及其对应文件之间的关联,以便可以重用文件描述符。如果调用成功,将返回0,错误将返回-1。
其语法格式如下:
#包括unistd.h
int close(int fildes);
这里要注意的是,检查close的返回值非常重要。有些文件系统,尤其是网络文件系统,在写文件时直到文件关闭才报告写错误,这将导致在执行写操作时数据并没有实际写入文件。
正在运行的程序可以同时打开的文件数量是有限制的。这个限制由limits.h中定义的OPEN_MAX值决定,它因系统而异,但POSIX至少需要16。此限制可能会受到当地系统限制的影响。
输出控制
Ioctl是一些东西的集合。它提供了一个接口来控制设备的形状及其描述符和服务的配置。终端、文件描述符、套接字,甚至磁带都有自己定义的ioctl调用。我们可以查看相关的手册页了解更多细节。POSIX只为流定义了ioctl。其语法格式如下:
#包括unistd.h
int ioctl(int fildes,int cmd,);
Ioctl将在对应于文件描述符fildes的目标上执行cmd指示的函数。根据特定设备提供的功能,它可能有第三个可选参数。
现在我们已经对打开、读取和写入系统调用有了足够的了解,我们可以编写一个低级程序copy_system.c,将一个文件的内容一个字符一个字符地复制到另一个文件中。
(在整个讨论中,我们将使用不同的方法来编写这个程序,以便我们可以比较不同方法之间的效率问题。为了简单起见,我们假设输入文件存在,但是输出文件不存在,并且所有的读写操作都是成功的。当然,在真实的程序设计中,我们会检查这些假设是否真的存在)。
#包括unistd.h
#包含系统/统计信息
#包含fcntl.h
#包含stdlib.h
int main()
{
char c;
int in,out
in=open("file.in ",O _ RDONLY);
out=open("file.out ",O_WRONLYO_CREAT,S _ I rusr S _ IWUSR);
while(read(in,c,1)==1
write(out,c,1);
退出(0);
}
这里要注意的是,# includeinstd.h必须放在第一行,因为它定义了POSIX编译相关的标签,这些标签会影响到其他包含的文件。
首先,我们需要创建一个大小为1Mb的测试输入文件,并将其命名为file.in .
如果我们运行这个程序,我们将得到以下输出:
$ TIMEFORMAT=" "时间副本_系统
4.67用户146.90系统2:32.57消耗了99%的CPU
.
$ ls -ls file.in file.out
尼尔用户1048576年9月17日10:46
1029 -rw - 1 neil用户1048576 9月17日10:51 file.out
这里,我们用时间程序来衡量运行这个程序所需的时间。TIMEFORMAT变量用于覆盖Linux系统中POSIX的默认时间输出格式,但默认情况下它不包括CPU使用量。从这个输出结果我们可以看到,在这个比较老的系统上,1Mb的文件file.in被成功复制到file.out,然而这个I/O文件只有所有者本人的读写权限。但是这个程序运行需要2.5分钟,几乎占用了所有的CPU运行时间。他之所以这么慢,是因为他用了200万次系统调用。
近年来,Linux在系统调用和文件系统方面有了很大的进步。相比较而言,在2.4的内核上测试不到5秒。
$ TIMEFORMAT=" "时间副本_系统
1.07用户3.50系统0:04.77消耗了95%的CPU
.
我们可以通过一次复制更大的块来改进它。在下面改进的程序copy_block.c中,一次复制1k字节,还使用了系统调用:
#包括unistd.h
#包含系统/统计信息
#包含fcntl.h
#包含stdlib.h
int main()
{
炭块[1024];
int in,out
int nread
in=open("file.in ",O _ RDONLY);
out=open("file.out ",O_WRONLYO_CREAT,S _ I rusr S _ IWUSR);
while((nread=read(in,block,sizeof(block))) 0)
write(out,block,n read);
退出(0);
}
现在让我们运行这个程序。首先,删除旧的输出文件:
$ rm文件. out
$ TIMEFORMAT="" time copy_block
0.00用户0.01系统0:00.01消耗了62%的CPU
.
现在,这个程序只需要百分之一秒,它只需要大约2000次系统调用。当然,这个时间会因系统而异,但它们显示了系统调用的大量开销,因此它们的使用值得优化。
管理文件的其他系统调用
还有许多其他系统调用可以用来处理这种低级文件描述符。这些允许程序控制如何使用一个并返回状态信息。
移动文件指针
lseek系统调用可用于设置文件描述符fildes的读或写指针。也就是说,我们可以设置读写发生的位置。我们可以用绝对地址来设置文件中的文件指针,或者用相对位置来设置文件的当前位置或文件的结尾。
其语法格式如下:
#包括unistd.h
#包含sys/types.h
off_t lseek(int fildes,off_t offset,int where);
offset参数用于指定位置,when参数用于指定如何使用偏移量。when的值可以是下列值之一:
SEEK_SET:offset是绝对地址。
offset是当前位置的相对地址。
SEEK_END:offset是到文件末尾的相对位置。
lseek的返回值是从设置了文件指针的文件开始以字节为单位测量的偏移值,如果失败将返回-1。lseek操作中使用的off_t类型是sys/types.h中定义的独立实现.
fstat,stat,lstat
fstat系统调用将返回与打开的文件描述符相对应的文件的状态信息。这个信息将被写入一个结构buf,buf的地址作为参数传递。
它们的语法格式如下:
#包括unistd.h
#包含系统/统计信息
#包含sys/types.h
int fstat(int fildes,struct stat * buf);
int stat(const char *path,struct stat * buf);
int lstat(const char *path,struct stat * buf);
我们在这里包含的sys/types.h文件是可选的,但是我们建议您在使用系统调用时这样做,因为它们的一些定义采用了标准的类型别名,这些别名可能会改变。
相关的函数stat和lstat将返回一个命名文件的状态信息。它们会产生相同的结果,但是当文件是符号链接时会有一些不同。lstat将返回该链接的信息,而stat将返回该链接指向的文件的信息。
stat结构的成员因系统而异,但一般来说,有如下一些数据:
St_mode文件权限和文件类型信息
st_ino文件的I节点信息
st_dev文件所在的设备信息
st_uid文件所有者的用户ID
st_gid文件所有者的组ID
st_atime的最后访问时间
st_ctime对权限、所有者、组或内容的上次修改时间
st_mtime内容的上次修改时间
St_nlink指向此文件的硬链接数
stat结构返回的st_mode还包含一些头文件SYS/STAT中定义的相关宏。h .这些宏包括权限名称、标记文件类型以及使用无助于测试某些特殊类型和权限的内容。
权限与前面提到的开放系统调用的权限相同。文件类型标签包括以下内容:
实体是一个特殊的块设备。
S_IFDIR:实体是一个目录。
实体是一个特殊的字符设备。
S_IFIFO:实体是一个IFIFO(命令管道)
实体是一个常规文件。
实体是一个符号链接。
的其他一些模式标记如下:
S_ISUID: UID是在实体的执行权限上设置的。
S_ISGID:实体在执行权限上设置了GID。
用于解释st_mode的掩码如下:
S_IFMT:文件类型
S_IRWXU:用户读/写/执行权限
S_IRWXG:组读/写/执行权限
S_IRWXO:其他用户的读/写/执行权限
还有一些定义的宏来帮助我们确定文件类型。这些只是将适当的掩码模式标签与适当的类型标签进行比较。它们包括:
S_ISBLK:测试特殊块文件
S_ISCHR:测试特殊字符文件
对目录的测试
S_ISFIFO:测试FIFO。
S_ISREG:测试常规文件。
测试符号链接。
例如,要测试一个不是目录并且为所有者设置了execute权限但没有其他用户权限的目录,我们可以使用以下测试:
struct stat statbuf
mode_t模式;
stat("文件名",statbuf);
modes=statbuf.st _ mode
如果(!S _ ISDIR(modes)(modes S _ irw Xu)==S _ IXUSR
.
Dup和dup2
dup系统调用提供了一种复制文件描述符的方法,它可以为我们访问同一个文件提供两个或更多的描述符。这可以用来读写文件中的不同位置。dup系统生成文件描述fildes的副本,并返回新的描述符。通过指定用于复制的描述符,dup2系统可以有效地将一个文件描述符复制到另一个文件描述符。
其语法格式如下:
#包括unistd.h
int dup(int fildes);
int dup2(int fildes,int fildes 2);
当我们通过管道与多个进程通信时,这些调用将非常有用。我们将在以后更详细地讨论dup系统。