簡體   English   中英

重定向標准輸出,不了解行為

[英]Redirecting stdout, don't understand behavior

我一直在嘗試使用dup2進行簡單的I / O重定向。 我完全遵循了別人所說的代碼,但是仍然沒有成功。

int out = open("stdoutput", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
printf("STANDARD OUT\n");
dup2(out, 1);
printf("SEND TO FILE\n");
dup2(1, out);
close(out);
printf("BACK TO STANDARD OUT\n");

這會將STANDARD OUT打印到終端,並發送到FILE BACK TO STANDARD OUT到文件。 為什么不切換回去?

我也想將fork / exec輸出標准輸出輸出到文件。

int out2 = open("execout", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
printf("STANDARD OUT\n");
dup2(out2, 1);
if(fork() == 0)
{
    execvp("time", NULL);
    perror(NULL);
}

dup2(out2, 1);
close(out2);
printf("BACK TO STANDARD OUT\n");

這將打印到終端:

STANDARD OUT TERM_PROGRAM = Apple_Terminal:無此類文件或目錄0.00真實0.00用戶0.00 sys

並輸出到文件execout,它打印:返回標准輸出

exec調用時間似乎還存在一些其他問題(找不到它,然后仍然打印嗎?),但我的主要問題是I / O重定向無法正常工作。

在此先感謝您的幫助。


更新:似乎有一個問題專門與exec不發送輸出到文件。 編碼:

int output_file = open("gcc_output", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);

if(fork() == 0)
{
    dup2(output_file, 1);
    close(output_file);
    char *args[] = {"gcc", path, NULL};
    printf("THIS GOES TO FILE");
    execvp(args[0], args); // gcc output, errors etc. go to terminal
    perror("exec");
    exit(2);
}

exec會導致它丟失文件描述符或其他內容嗎?

dup2(from, to)將文件描述符from復制到文件描述符to ; 如果to打開,則在被覆蓋之前將其默默關閉。

在第一個示例中,打開文件stdoutput進行寫入; 給出盡可能低的描述符編號(可能為3); 然后您的dup2(out2, 1)將此描述符復制到標准輸出描述符1上; 原始標准輸出被靜默關閉。 現在有4個打開的描述符:

  • 0是原始標准輸入
  • 1已打開以寫入文件stdoutput
  • 2是原始標准輸出
  • 3打開以寫入文件stdoutput

最后,您嘗試通過在文件描述符3上復制文件描述符1來“恢復”原始標准輸出。

相反,您應該通過dup原始標准輸出存儲到另一個文件描述符中:

int out = open("stdoutput", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
printf("STANDARD OUT\n");
int saved_stdout = dup(1); // create a copy of the stdout file descriptor
dup2(out, 1);
close(out);                // close the extra descriptor
printf("SEND TO FILE\n");
dup2(saved_stdout, 1);     // copy the saved stdout file descriptor to 1
close(saved_stdout);       // close the copy of stdout
printf("BACK TO STANDARD OUT\n");

您的execvp調用也斷開了; 應該有其他參數作為命令名稱; time也不會顯示當前日期,但是命令是否需要另一個命令作為參數-也許您想執行date命令? 此外,你會想要做的dup2 只有在fork之后子進程! 請嘗試以下操作:

int out2 = open("execout", O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
printf("STANDARD OUT\n");
if (fork() == 0) {
    dup2(out2, 1);
    close(out2);
    execvp("date", "date", (char *)NULL);
    perror("exec");
    exit(2);
}
close(out2);
printf("STILL POINTING TO STANDARD OUT\n");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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