因此,我试图将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;
}
答案 0 :(得分:0)
使用functionOutput()
,您可以很好地尝试将系统命令的输出捕获到文件中。实际上, that 是第一个参数为1
时调用的函数,因此您可能要更新注释。另外,您正在创建一个文件,其名称存储在argv[1]
中,我们已经知道它的名称为1
,因此它可能未达到您的期望,并且可能需要:
ofd = open(argv[2], O_CREAT|O_TRUNC|O_WRONLY);
使用functionInput()
,您正在从文件中读取第一个非空白条目。如果您告诉它读取使用functionOutput()
函数输出的文件,则可能是ls
列出的第一个文件的名称(其中一部分)。
我发现不清楚您想做什么,不是那样。如果您想找出运行该命令以生成输出的内容,则该信息无法从文件本身获得,因为您未在其中写入信息。如果这是您想要的,则可能需要考虑将命令写为文件的第一行,然后是输出。然后,当您阅读它时,可以假定第一行是命令运行,然后是该命令的输出。
答案 1 :(得分:0)
要重定向输入和输出,请使用此格式
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;
来重定向相反的方式。
接下来,要使用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;
}
答案 2 :(得分: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()
使用{ {1}}(以秒和纳秒为单位。”)
使用/输出示例
struct timespec