程序试图实现的输出是什么
What is the output that the program trying to achieve
我知道 fork()、dup2 调用,但我无法推断程序的输出。
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, char *argv[]){
pid_t pid1, pid2;
int fds[2];
char *argv1[] = { "ls", "-l","usr/bin", NULL};
char *argv2[] = {"more", NULL};
pipe(fds);
pid1=fork();
if(!pid1){
close(fds[0]);
dup2(fds[1], STDOUT_FILENO);
close(fds[1]);
execvp(argv1[0],argv1);
}
pid2=fork();
if(!pid2){
close(fds[1]);
dup2(fds[0], STDOUT_FILENO);
close(fds[0]);
execvp(argv1[0],argv2);
}
close(fds[0]);
close(fds[1]);
waitpid(pid2,NULL,0);
return EXIT_SUCCESS;
}
此外,如果我进行实验并在最后调用 waitpid 时错误地按 pid1 而不是 pid2 会发生什么情况。
名义上,程序是运行 shell 管道
ls -l usr/bin | more
在实践中,与 more
的连接处理不当(如果不进行所有必要的更改,使用复制和粘贴是危险的)。它将管道的读取端连接到 more
的标准输出,这简直是坏掉了。它还会第二次运行 ls
(将 argv1[0]
传递给 execvp()
而不是 argv2[0]
),但告诉 ls
它的名称是 more
。它也不相信 execvp()
会失败——但它会失败。
有了这些最小的修复(程序不包括 <stdio.h>
所以没有错误报告),你会得到类似的东西:
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
pid_t pid1, pid2;
int fds[2];
char *argv1[] = { "ls", "-l", "usr/bin", NULL };
char *argv2[] = { "more", NULL };
pipe(fds);
pid1 = fork();
if (pid1 == 0)
{
close(fds[0]);
dup2(fds[1], STDOUT_FILENO);
close(fds[1]);
execvp(argv1[0], argv1);
exit(EXIT_FAILURE);
}
pid2 = fork();
if (pid2 == 0)
{
close(fds[1]);
dup2(fds[0], STDIN_FILENO);
close(fds[0]);
execvp(argv2[0], argv2);
exit(EXIT_FAILURE);
}
close(fds[0]);
close(fds[1]);
waitpid(pid2, NULL, 0);
return EXIT_SUCCESS;
}
我调用了程序 pipe31
(从 pipe31.c
创建)并得到示例输出:
$ pipe31
ls: usr/bin: No such file or directory
$ mkdir -p usr/bin
$ random -n 15 1000 9999 > usr/bin/polyglot
$ pipe31
total 8
-rw-r--r-- 1 jonathanleffler staff 75 Dec 8 22:07 polyglot
$
当如图所示调用时,本地 random
程序在 1000 到 9999 之间创建 15 个随机数,每个随机数在其自己的行上 — 对应于文件中的 75 个字节。输出是通过 more
传输的,但很难在网络浏览器中发现它。
至于你提议的实验——实验吧——你不会造成伤害。您看到的内容将取决于您正在使用的目录的大小,以及您的终端的大小 window。但是,如果 ls -l
的输出足够大(但不是太大),那么您会在 ls
列表的中间得到一个 shell 提示,并且您会more
显示数据并等待读取换行符。 shell 和 more
之间可能会就以下输入进行竞争,这可能会很有趣。这假设您在试验之前解决了其余答案中确定的问题。
我知道 fork()、dup2 调用,但我无法推断程序的输出。
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, char *argv[]){
pid_t pid1, pid2;
int fds[2];
char *argv1[] = { "ls", "-l","usr/bin", NULL};
char *argv2[] = {"more", NULL};
pipe(fds);
pid1=fork();
if(!pid1){
close(fds[0]);
dup2(fds[1], STDOUT_FILENO);
close(fds[1]);
execvp(argv1[0],argv1);
}
pid2=fork();
if(!pid2){
close(fds[1]);
dup2(fds[0], STDOUT_FILENO);
close(fds[0]);
execvp(argv1[0],argv2);
}
close(fds[0]);
close(fds[1]);
waitpid(pid2,NULL,0);
return EXIT_SUCCESS;
}
此外,如果我进行实验并在最后调用 waitpid 时错误地按 pid1 而不是 pid2 会发生什么情况。
名义上,程序是运行 shell 管道
ls -l usr/bin | more
在实践中,与 more
的连接处理不当(如果不进行所有必要的更改,使用复制和粘贴是危险的)。它将管道的读取端连接到 more
的标准输出,这简直是坏掉了。它还会第二次运行 ls
(将 argv1[0]
传递给 execvp()
而不是 argv2[0]
),但告诉 ls
它的名称是 more
。它也不相信 execvp()
会失败——但它会失败。
有了这些最小的修复(程序不包括 <stdio.h>
所以没有错误报告),你会得到类似的东西:
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
pid_t pid1, pid2;
int fds[2];
char *argv1[] = { "ls", "-l", "usr/bin", NULL };
char *argv2[] = { "more", NULL };
pipe(fds);
pid1 = fork();
if (pid1 == 0)
{
close(fds[0]);
dup2(fds[1], STDOUT_FILENO);
close(fds[1]);
execvp(argv1[0], argv1);
exit(EXIT_FAILURE);
}
pid2 = fork();
if (pid2 == 0)
{
close(fds[1]);
dup2(fds[0], STDIN_FILENO);
close(fds[0]);
execvp(argv2[0], argv2);
exit(EXIT_FAILURE);
}
close(fds[0]);
close(fds[1]);
waitpid(pid2, NULL, 0);
return EXIT_SUCCESS;
}
我调用了程序 pipe31
(从 pipe31.c
创建)并得到示例输出:
$ pipe31
ls: usr/bin: No such file or directory
$ mkdir -p usr/bin
$ random -n 15 1000 9999 > usr/bin/polyglot
$ pipe31
total 8
-rw-r--r-- 1 jonathanleffler staff 75 Dec 8 22:07 polyglot
$
当如图所示调用时,本地 random
程序在 1000 到 9999 之间创建 15 个随机数,每个随机数在其自己的行上 — 对应于文件中的 75 个字节。输出是通过 more
传输的,但很难在网络浏览器中发现它。
至于你提议的实验——实验吧——你不会造成伤害。您看到的内容将取决于您正在使用的目录的大小,以及您的终端的大小 window。但是,如果 ls -l
的输出足够大(但不是太大),那么您会在 ls
列表的中间得到一个 shell 提示,并且您会more
显示数据并等待读取换行符。 shell 和 more
之间可能会就以下输入进行竞争,这可能会很有趣。这假设您在试验之前解决了其余答案中确定的问题。