我理解I / O重定向在Unix / Linux中是如何工作的,我知道Shell使用此功能来管理具有特殊类型文件的程序 - 匿名管道。但我想知道Shell如何以编程方式实现它的细节?我不仅对所涉及的系统调用感兴趣,而且对整个画面感兴趣。
例如ls | sort
,Shell如何为ls
和sort
执行I / O重定向?
答案 0 :(得分:3)
整个画面很复杂,最好的理解方法是研究一个小壳。对于有限的图片,这里是。在执行任何操作之前,shell会解析整个命令行,以便确切知道如何链接进程。让我们说它遇到了proc1 | PROC2。
它设置了一个管道。长话短说,写入thepipe[0]
最终会出现在thepipe[1]
int thepipe[2];
pipe(thepipe);
它会在exec
dup2 (thepipe[1], STDOUT_FILENO);
它执行新程序,该程序幸福地不知道重定向,只是写入stdout
,就像一个表现良好的过程
它分叉第二个进程并在exec
dup2 (thepipe[0], STDIN_FILENO);
它执行新程序,不知道其输入来自另一个程序
答案 1 :(得分:1)
这是来自silberschatz的书籍操作系统概念的示例程序
如果你知道fork()和相关的东西的概念,程序是不言自明的......希望这有帮助! (如果你还想要解释,我可以解释一下!)
显然,如果你想让它像
那样工作,你应该在这个程序中做一些更改(例如fork()等的更改) ls | sort
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#define BUFFER SIZE 25
#define READ END 0
#define WRITE END 1
int main(void)
{
char write msg[BUFFER SIZE] = "Greetings";
char read msg[BUFFER SIZE];
int fd[2];
pid t pid;
/* create the pipe */
if (pipe(fd) == -1) {
fprintf(stderr,"Pipe failed");
return 1;
}
/* fork a child process */
pid = fork();
if (pid < 0) { /* error occurred */
fprintf(stderr, "Fork Failed");
return 1;
}
if (pid > 0) { /* parent process */
/* close the unused end of the pipe */
close(fd[READ END]);
/* write to the pipe */
write(fd[WRITE END], write msg, strlen(write msg)+1);
/* close the write end of the pipe */
close(fd[WRITE END]);
}
else { /* child process */
/* close the unused end of the pipe */
close(fd[WRITE END]);
/* read from the pipe */
read(fd[READ END], read msg, BUFFER SIZE);
printf("read %s",read msg);
}
}
/* close the write end of the pipe */
close(fd[READ END]);
return 0;
}