
Unix 中一切皆文件。標準輸入(stdin, fd 0)、標準輸出(stdout, fd 1)、標準錯誤(stderr, fd 2)本質是預打開的文件描述符。利用 dup2(oldfd, newfd) 可將任意文件描述符複製到標準描述符位置,實現透明重定向:
dup2(fd1, 0); // 標準輸入 ← fd1
dup2(fd2, 1); // 標準輸出 → fd2
dup2(fd3, 2); // 標準錯誤 → fd3
pipe(fildes) 返回 fildes[0](讀端)、fildes[1](寫端)。fildes[0],將 stdout(1) 重定向到寫端 fildes[1]。fildes[1],將 stdin(0) 重定向到讀端 fildes[0]。
#include <unistd.h>
#include <stdio.h>
int main() {
int fildes[2];
pid_t pid;
char buf[256];
if (pipe(fildes) < 0 || (pid = fork()) < 0) {
fprintf(stderr, "pipe/fork failed\n");
return 1;
}
if (pid == 0) { // 子進程
close(fildes[1]); // 關閉寫端
dup2(fildes[0], 0); // stdin ← 管道讀端
close(fildes[0]);
gets(buf); // 實際讀取父進程 stdout
fprintf(stderr, "child:[%s]\n", buf);
return 2;
}
// 父進程
close(fildes[0]); // 關閉讀端
dup2(fildes[1], 1); // stdout → 管道寫端
close(fildes[1]);
puts("Hello!"); // 輸出自動流向子進程 stdin
return 0;
}
# ./pipe3
child:[Hello!]
父進程 puts("Hello!") 未顯示在終端,而是經管道傳給子進程,子進程 gets() 讀取後打印到 stderr,驗證重定向成功。
cmd1 | cmd2 本質是將 cmd1 stdout 接 cmd2 stdin。socketpair(AF_UNIX, SOCK_STREAM, 0, fds) 替代管道,支持全雙工、可傳遞文件描述符。掌握管道重定向模型,是編寫高可靠 Unix 系統工具、服務器框架、自動化測試平台的基石。