好吧,有十億個演示涉及到dup,dup2,fcntl,管道和各種各樣的東西,當多個進程存在時都很棒。然而,我還沒有看到一個非常基本的東西,我認爲這將有助於解釋管道的行爲及其與標準輸出和輸入的關係。如何使用dup和/或dup2將標準重定向到管道,然後輸出到antoher管道然後返回標準輸出?
我的目標是簡單地(在相同的過程中)通過直接回到標準輸出。我已經完成了這個 的中間階段,它將管道輸出重定向到一個文件或寫入緩衝區......然後將標準輸出回到它開始的位置。在那一點上,我當然可以將緩衝區寫回stdout,但我不想這樣做。
由於我將標準輸出移動到文件表中的另一個位置,因此我希望將管道的輸出直接送入新的標準輸出位置,並像平常一樣將其打印出來。
我覺得有一種圍繞文件表的圖層,我不理解。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int main() {
int pipeEnds_arr1[2];
char str1[] = "STRING TO FEED INTO PIPE \n"; // make a string array
pipe(pipeEnds_arr1);
printf("File Descriptor for pipe ends from array\nPOSITION out 0 : %d\nPOSITION in 1 : %d\n", pipeEnds_arr1[0], pipeEnds_arr1[1]);
/* now my goal is to shift the input of the pipe into the position of
* standard output, so that the print command feeds the pipe, then I
* would like to redirect the other end of the pipe to standard out.
*/
int someInt = dup(1); // duplicates stdout to next available file table position
printf ("Some Int FD: %d\n", someInt); // print out the fd for someInt just for knowing where it is
/* This is the problem area. The out end of the pipe never
* makes it back to std out, and I see no way to do so.
* Stdout should be in the file table position 5, but when
* I dup2 the output end of the pipe into this position ,
* I believe I am actually overwriting std out completely.
* But I don't want to overwrite it, i want to feed the output
* of the pipe into std out. I think I am fundamentally
* misunderstanding this issue.
*/
dup2(pipeEnds_arr1[1], 1); //put input end of pipe into std out position
//dup2(pipeEnds_arr1[0], 5); // this will not work
//and other tests I have conducted do not work
printf("File Descriptor for pipe ends from array\nPOSITION out 0 : %d\nPOSITION in 1 : %d\n", pipeEnds_arr1[0], pipeEnds_arr1[1]);
fflush(stdout);
close(pipeEnds_arr1[0]);
close(pipeEnds_arr1[1]);
return 0;
}
編輯********* OK,我知道那是什麼莫名其妙的std出需要的信息從如printf命令,然後擊潰它變成一個緩衝區,然後刷新到外殼。
我相信,必須有一種方法來將管道的「讀取」或輸出端路由到同一個緩衝區,然後到達shell。我已經想出瞭如何將管道輸出路由到一個字符串中,然後我可以隨心所欲地做到這一點。在示例代碼下面我發佈,我會先擊潰管出一個字符串,然後打開一個文件,並寫入字符串到文件的打開的文件描述符...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int main() {
/* Each pipe end array has to have 2 positions in it. The array
* position represents the two pipe ends with the 0 index
* position representing the output of the pipe (the place you want
* read your data from), and 1 index position representing the
* input file descriptor of the pipe (the place you want to write
* your data).
*/
int pipeEnds_arr1[2];
char str1[] = "Hello, we are feeding this into the pipe that we are through stdout into a pipe and then reading from the pipe and then feeding that output into a file \n"; // make a string array
/* Here we want to actually do the pipe command. We feed it the array
* with the 2 positions in it which will now hold file descriptors
* attached to the current process which allow for input and output
* through the new pipe. At this point, we don't know what the
* exact file decriptors are, but we can look at them by printing
*/
pipe(pipeEnds_arr1);
printf("File Descriptor for pipe ends from array\nPOSITION out 0 : %d\nPOSITION in 1 : %d\n", pipeEnds_arr1[0], pipeEnds_arr1[1]);
/* now my goal is to shift the input of the pipe into the position of
* standard output, so that the print command feeds the pipe, then we
* will try to read from the pipe and redirect the output to the std
* or in this test case out to a file.
*/
int someInt = dup(1); // we moved what was stdout into someInt;
/* put the write end of the pipe in the old stdout position by
* using dup2 so we will print directly into the pipe
*/
dup2(pipeEnds_arr1[1], 1);
/* this is where id like to re-rout the pipe back to stdout but
* im obviously not understanding this correctly
*/
//dup2(someInt, 3);
/* since std out has now been replaced by the pipe write end, this
* printf will print into the pipe
*/
printf("%s", str1);
/* now we read from the pipe into a new string we make */
int n;
char str2[strlen(str1)];
n = read(pipeEnds_arr1[0], str2, sizeof(str2)-1);
str2[n] = 0;
/* open a file and then write into it from the output of the pipe
* that we saved into the str2
*/
int fd = open("tmp.out", O_WRONLY | O_CREAT | O_TRUNC, 0644);
write(fd, str2, strlen(str2));
/* not sure about these last commands and their relevance */
fflush(stdout);
close(pipeEnds_arr1[0]);
close(pipeEnds_arr1[1]);
close(fd);
return 0;
}
標準輸出是* always *文件描述符'1'。 'someInt'中的描述符與'dup2'調用後的描述符'1'不同。 'dup'系統調用*重複*描述符,它不使用引用或鏈接或類似的東西。另外,'dup'調用不會修改您傳遞的描述符號碼。 'pipeEnds_arr1 [1]'不會在'pipe'調用之後改變值(描述符號)。 –
這在任何情況下都無法工作。管的一端用於書寫,另一端用於書寫。所以你可以用管道的寫入端來替換'stdout',並且你的程序可以在管道中寫入東西(認爲它寫入'stdout')。但是管道的另一端不能直接連接到原來的'stdout'。某些代碼需要從管道中讀取並將數據寫入原始的「stdout」。 – user3386109
即使在理論上這也不行,因爲它會造成無限循環。考慮一下 - 你最終會將stdout的輸出回饋給自己。 – kfx