在 POSIX C 中将标准输出重定向到标准输入
Redirecting stdout to stdin in POSIX C
我正在尝试编写一个将 stdout
重定向到 stdin
的程序,主要是为了更好地理解 dup2()
的工作原理。我试着写了一个简单的程序,如果你 printf()
一些东西,你可以稍后 scanf()
它回来,但没能让它工作。首先,我尝试只使用 dup2(0, 1)
,认为它会将 stdout
(1) 重定向到 stdin
(0)。这没有用。我认为,由于一个用于输入,另一个用于输出,它们可能不兼容,所以我尝试使用管道来执行此操作,如下所示:
#include <stdio.h>
#include <unistd.h>
int main() {
int pipe_desc[2];
pipe(pipe_desc);
dup2(pipe_desc[0], 0);
dup2(pipe_desc[1], 1);
printf("foo");
char bar[20];
scanf("%s", bar);
fprintf(stderr, "%s", bar);
}
然而,据我所知,现在即使 printf
应该将 "foo"
放入管道,当我调用 scanf
时,程序只是挂在那里,并且既不从标准输入也不从管道读取。怎么了?这段代码到底发生了什么?可以在没有管道(或与此相关的任何其他辅助结构)的情况下完成这种重定向吗?
你的工作原理,代码里有解释。
#include <stdio.h>
#include <unistd.h>
int main() {
int pipe_desc[2];
pipe(pipe_desc);
printf("pid = %d \n",getpid());
/* above statement creates 2 descriptors 3 & 4. 3 is for read and 4 is for write**/
dup2(pipe_desc[0], 0);
/** 3 is duplicates with 0(stdin) i.e if you try to do scanf, it won't scan from keyboard, it will scan from pipe(read end, for that make sure something should be there in pipe **/
dup2(pipe_desc[1], 1);
/** 4 is duplicates with 1 (stdout) i.e if you try to write onto screen, it won't. It will try into pipe write end **/
/** SO TILL NOW FD DETAILS
0,3 --> PIPE_DESC[0]
1,4 --> PIPE_DESC[1]
**/
#if 1
fflush(stdout);
printf("foo\n");//it won't print
char bar[20];
scanf("%s", bar);//it won't scan bcz 0 is poiting to pipe_desc[0]
#endif
/** YOU CAN CHECK USING OTHER TERMINAL "ls -l /proc/pid/fd/" **/
fprintf(stderr, "%s", bar);// fd 2 is still available.So foo gets printed on screen
}
在上面的程序运行中打开另一个终端,使用
查看fd详情
root@xyz-PC:/home/achal/s_flow/cpp# ls -l /proc/4503/fd
total 0
lr-x------ 1 root root 64 Jan 15 16:45 0 -> pipe:[782489]
l-wx------ 1 root root 64 Jan 15 16:45 1 -> pipe:[782489]
lrwx------ 1 root root 64 Jan 15 16:45 2 -> /dev/pts/9
lr-x------ 1 root root 64 Jan 15 16:45 3 -> pipe:[782489]
l-wx------ 1 root root 64 Jan 15 16:45 4 -> pipe:[782489]
我正在尝试编写一个将 stdout
重定向到 stdin
的程序,主要是为了更好地理解 dup2()
的工作原理。我试着写了一个简单的程序,如果你 printf()
一些东西,你可以稍后 scanf()
它回来,但没能让它工作。首先,我尝试只使用 dup2(0, 1)
,认为它会将 stdout
(1) 重定向到 stdin
(0)。这没有用。我认为,由于一个用于输入,另一个用于输出,它们可能不兼容,所以我尝试使用管道来执行此操作,如下所示:
#include <stdio.h>
#include <unistd.h>
int main() {
int pipe_desc[2];
pipe(pipe_desc);
dup2(pipe_desc[0], 0);
dup2(pipe_desc[1], 1);
printf("foo");
char bar[20];
scanf("%s", bar);
fprintf(stderr, "%s", bar);
}
然而,据我所知,现在即使 printf
应该将 "foo"
放入管道,当我调用 scanf
时,程序只是挂在那里,并且既不从标准输入也不从管道读取。怎么了?这段代码到底发生了什么?可以在没有管道(或与此相关的任何其他辅助结构)的情况下完成这种重定向吗?
你的工作原理,代码里有解释。
#include <stdio.h>
#include <unistd.h>
int main() {
int pipe_desc[2];
pipe(pipe_desc);
printf("pid = %d \n",getpid());
/* above statement creates 2 descriptors 3 & 4. 3 is for read and 4 is for write**/
dup2(pipe_desc[0], 0);
/** 3 is duplicates with 0(stdin) i.e if you try to do scanf, it won't scan from keyboard, it will scan from pipe(read end, for that make sure something should be there in pipe **/
dup2(pipe_desc[1], 1);
/** 4 is duplicates with 1 (stdout) i.e if you try to write onto screen, it won't. It will try into pipe write end **/
/** SO TILL NOW FD DETAILS
0,3 --> PIPE_DESC[0]
1,4 --> PIPE_DESC[1]
**/
#if 1
fflush(stdout);
printf("foo\n");//it won't print
char bar[20];
scanf("%s", bar);//it won't scan bcz 0 is poiting to pipe_desc[0]
#endif
/** YOU CAN CHECK USING OTHER TERMINAL "ls -l /proc/pid/fd/" **/
fprintf(stderr, "%s", bar);// fd 2 is still available.So foo gets printed on screen
}
在上面的程序运行中打开另一个终端,使用
查看fd详情root@xyz-PC:/home/achal/s_flow/cpp# ls -l /proc/4503/fd
total 0
lr-x------ 1 root root 64 Jan 15 16:45 0 -> pipe:[782489]
l-wx------ 1 root root 64 Jan 15 16:45 1 -> pipe:[782489]
lrwx------ 1 root root 64 Jan 15 16:45 2 -> /dev/pts/9
lr-x------ 1 root root 64 Jan 15 16:45 3 -> pipe:[782489]
l-wx------ 1 root root 64 Jan 15 16:45 4 -> pipe:[782489]