簡體   English   中英

重定向標准輸入和標准輸出?

[英]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/pselectpoll就是您想要的。

例如, 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM