[英]Redirecting stdin and stdout?
因此,我嘗試將I / O重定向為從文件讀取命令,然后當用戶運行輸出命令時,它將打印已編譯的命令以輸出文件。
例如在終端上:
./run 2 < test.txt // This would take file using dup and take the input
然后,當您要輸出編譯時:
./run 1 > output.txt // and it would put into an output file
到目前為止,我知道如何輸出到文件,但是我的問題是輸入。 如何使用dup2()
函數從文件中獲取命令? 我嘗試研究這個,但是沒有運氣。
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
char inputForOutput[100];
void functionOutput(int argc, char **argv){
int ofd; //Init of file desc.
ofd = open(argv[1], O_CREAT|O_TRUNC|O_WRONLY);
dup2(ofd, 1);//Duplicates to stdout
system("ls");//Copies commnd given to output_file
}
//Function is called when argument number is == 1
void functionInput(int argc, char **argv){
FILE *ifd;
printf("\n %s \n ", argv[2]);
ifd = fopen(argv[2] , "r");
if (ifd == NULL){
perror("No file found");
exit(1);
}
fscanf(ifd,"%s",inputForOutput);
printf("\n**%s**\n",inputForOutput);
}
int main(int argc, char **argv)
{
int output;
int input;
output = strcmp("1", argv[1]);
input = strcmp("2" ,argv[1]);
if (output == 0 ) { //Fail safe for number of arguments
functionOutput(argc, argv);
}
else if ( input == 0){
functionInput(argc, argv);
}
else{
fprintf(stderr, "How to use: %s function output_file\n", argv[0]); // FAIL SAFE IF INPUT DOES NOT MATCH BOTH FUNCTIONS
}
return 0;
}
使用functionOutput()
可以很好地嘗試將系統命令的輸出捕獲到文件中。 實際上, 這是第一個參數為1
時調用的函數,因此您可能要更新注釋。 另外,您正在創建一個文件,該文件的名稱存儲在argv[1]
,我們已經知道它是1
所以它可能未達到您的期望,並且您可能想要:
ofd = open(argv[2], O_CREAT|O_TRUNC|O_WRONLY);
使用functionInput()
您將從文件中讀取第一個非空白條目。 如果您告訴它讀取使用functionOutput()
函數輸出的文件,則可能是ls
列出的第一個文件的名稱(其中的一部分)。
我發現不清楚您想做什么,不是那樣。 如果您想找出運行該命令以生成輸出的內容,則該信息無法從文件本身獲得,因為您未在其中寫入信息。 如果這是您想要的,則可能需要考慮將命令寫為文件的第一行,然后是輸出。 然后,當您閱讀它時,可以假定第一行是命令運行,然后是該命令的輸出。
要重定向輸入和輸出,請使用此格式
myprogram > out.txt < in.txt //read from in.txt, write to out.txt myprogram < in.txt > out.txt //read from in.txt, write to out.txt myprogram < in.txt //redirect stdin only myprogram > out.txt //redirect stdout only myprogram //no redirection ...
這適用於任何程序。 例:
int main(void)
{
char buf[1000];
if(fgets(buf, sizeof(buf), stdin))
printf("write: %s\n", buf);
return 0;
}
要在程序中重定向stdin / stdout,請使用標准方法
freopen("output.txt", "w", stdout);
printf("Testing...");
fclose(stdout);
freopen("input.txt", "r", stdin);
char buf[100];
fgets(buf, sizeof(buf), stdin);
fclose(stdin);
或者,設置FILE *fin = stdin; FILE* fout = stdout;
FILE *fin = stdin; FILE* fout = stdout;
重定向相反的方式。
接下來,要使用argv
元素編寫程序,請始終先測試argc
。 下面的代碼顯示了一個示例。
#include <stdio.h>
#include <string.h>
int redirect(int argc, char **argv, int *index)
{
//no more redirection!
if(*index >= argc)
return 1;
//not enough parameters
if(*index + 1 >= argc)
{
printf("wrong usage\n");
return 0;
}
if(strcmp(argv[*index], "<") == 0)
{
*index++; //next parameter is to redirect input
if(!freopen(argv[*index], "r", stdin))
printf("error, redirect input failed");
}
else if(strcmp(argv[*index], ">") == 0)
{
*index++; //next parameter is to redirect output
if(!freopen(argv[*index], "w", stdout))
printf("error, redirect output failed");
}
else
{
printf("wrong usage\n");
return 0;
}
return 1;
}
int main(int argc, char **argv)
{
int index = 1;
if(!redirect(argc, argv, &index))
return 1;
if(!redirect(argc, argv, &index))
return 1;
//read
char buf[1000];
if(fgets(buf, sizeof(buf), stdin))
{
//write
printf("write: %s\n", buf);
}
fclose(stdin);
fclose(stdout);
return 0;
}
如果我理解您的問題,並且您想以兩種不同的模式運行程序,(1)如果要在stdin
上進行輸入,則希望進行輸入; (2)如果沒有輸入等待,您想做一個輸出,然后select/pselect
或poll
就是您想要的。
例如, select
允許您檢查是否已准備好在文件描述符(或一組描述符)上讀取輸入,並且它將返回輸入等待的描述符數目(或-1
並在錯誤時設置errno
)。 您可以簡單地使用STDIN_FILENO
(a / k / a fd 0
)檢查stdin
上是否有輸入,例如
#include <stdio.h>
#include <unistd.h> /* for STDIN_FILENO */
#include <sys/select.h> /* for pselect */
int input (int filedes)
{
fd_set set;
/* declare/initialize zero timeout */
struct timespec timeout = { .tv_sec = 0 };
/* Initialize the file descriptor set. */
FD_ZERO (&set);
FD_SET (filedes, &set);
/* check whether input is ready on filedes */
return pselect (filedes + 1, &set, NULL, NULL, &timeout, NULL);
}
int main (void)
{
if (input (STDIN_FILENO))
puts ("doing input routine");
else
puts ("doing output routine");
return 0;
}
( 注意:在手冊頁上,“ select()
使用的超時是struct timeval
時間(以秒和微秒為單位),而pselect()
使用struct timespec
(以秒和納秒為單位)。”)
使用/輸出示例
$ ./bin/select_peekstdin < file
doing input routine
$ ./bin/select_peekstdin
doing output routine
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.