Linux中函数通过读取标准输入(fd 0)接收管道数据,因管道已将前序命令输出重定向至当前进程stdin;C用fgets/read、Python用sys.stdin、Shell用read或cat /dev/stdin即可获取。

在Linux中,函数本身不直接“接收管道”,真正接收的是进程的标准输入(stdin)。所谓“函数里接收标准输入管道”,本质是:该函数运行在某个进程中,而这个进程的stdin已被前一个命令通过|重定向为管道读端。只要函数内部用常规方式读取stdin(比如fgets()、read(0, ...)、scanf()等),就能拿到管道传来的数据。
函数如何读取管道输入
关键不是函数“主动连接管道”,而是它默认从文件描述符0(即stdin)读取——而系统已把fd 0连到了管道另一端。
- 用C语言写时,可直接调用
read(STDIN_FILENO, buf, size)或带缓冲的fgets(buf, size, stdin) - 用Python写时,用
sys.stdin.read()、input()或逐行迭代for line in sys.stdin: - Shell函数中,可用
read命令读取一行,或用cat /dev/stdin捕获全部输入
注意stdin是否被正确继承
如果函数封装在子进程中(比如用fork() + exec()启动新程序),需确保父进程没关闭管道读端,且子进程未重定向stdin。
- 常见错误:子进程执行
dup2(pipe_fd[0], STDIN_FILENO)后忘记close(pipe_fd[0]),导致管道不关闭、读端阻塞 - 若用
system()或poppen()等封装接口,它们通常自动继承父进程的stdin,无需额外操作
Shell函数示例:接收管道并处理
下面是一个能接收管道输入的Shell函数:
myfilter() {
while IFS= read -r line; do
if [[ "$line" =~ ^[a-zA-Z]+ ]]; then
echo "OK: $line"
fi
done
}使用方式:echo -e "apple\n123\nbanana" | myfilter → 输出两行以字母开头的内容。
C程序示例:main中读stdin即读管道
编译后执行ls / | ./myprog,程序就自然收到ls的输出:
#include <stdio.h>
int main() {
char line[256];
while (fgets(line, sizeof(line), stdin) != NULL) {
printf("got: %s", line);
}
return 0;
}</stdio.h>











