在Linux系统中,I/O重定向和管道是两种重要的进程间通信(IPC)方式,它们允许我们改变程序的标准输入、输出和错误流,或者在不同的进程中传递数据。本实验主要涵盖了这两个主题,通过编写和运行C语言程序来实践。
1. **I/O重定向**
I/O重定向允许我们将程序的输出重定向到文件,或将文件内容作为程序的输入。在`demo1.c`中,使用了`open()`和`close()`函数实现了输入重定向。程序读取用户从键盘输入的三行数据,然后关闭标准输入(文件描述符0),并用`open()`打开`/etc/passwd`文件作为新的标准输入。这样,后续的读取操作将从`/etc/passwd`文件中获取数据,而不是从键盘。
另一种实现重定向的方法是使用`dup2()`函数,如`demo2.c`所示。`dup2()`可以复制一个已存在的文件描述符,并将其指向另一个文件描述符。在这个例子中,创建了一个名为`ls.txt`的文件,然后使用`dup2()`将标准输出(文件描述符1)更改为`ls.txt`的文件描述符。这样,当调用`execl()`执行`/bin/ls`命令时,其输出会被重定向到`ls.txt`文件中。
2. **管道(Pipe)**
管道是一种临时的数据传输机制,用于在具有亲缘关系的进程之间传递数据。在`demo3.c`中,我们看到了无名管道的使用。程序创建了一个管道(`pipe(fd_arr)`),然后通过`fork()`创建了一个子进程。子进程关闭管道的写端(`fd_arr[1]`),然后从读端(`fd_arr[0]`)读取数据;而父进程则关闭读端,向写端写入数据。这个例子展示了父子进程如何通过管道进行通信,父进程向管道写入字符,子进程按顺序读取并打印出来。
命名管道(FIFO)与无名管道类似,但区别在于它是一个持久化的文件,可以在不同的时间由不同的进程读写。`demo4.c`创建了一个名为`fifo`的命名管道,`mkfifo()`函数用于此目的。之后,可以通过`open()`函数像操作普通文件一样打开并读写命名管道。
`demo5.c`和`demo6.c`可以用来演示如何向命名管道写入和读取数据。在`demo5.c`中,程序向`fifo`写入信息,而在`demo6.c`中,程序打开并读取`fifo`中的数据。这两个程序需要配合运行,以展示命名管道的功能。
通过这些实验,你可以深入理解Linux系统中I/O重定向和管道的工作原理,以及如何在C程序中实现它们。这些基础知识对于系统级编程和shell脚本编写非常重要,因为它们允许我们灵活地控制程序的输入输出,以及在不同进程之间传递数据。