標準文件描述符與標準文件句柄

思維導圖

本文並非闡述文件描述符與文件句柄的異同,而是標準

這是怎樣的標準呢?

fork創建一個進程,規定默認存在3個文件描述符,分別是

描述符編號 簡介 作用
0 標準輸入 通用於獲取輸入的文件描述符
1 標準輸出 通用輸出普通信息的文件描述符
2 標準錯誤 通用輸出錯誤信息的文件描述符

標準輸入比較好理解,在函數scanf中,就是從標準輸入獲取的數據。我們執行一個命令,只要此命令在前臺執行,標準輸入就是我們在終端的輸入。

標準輸出與標準錯誤用途是有差別的。從命名上我們就發現,標準錯誤用於輸出錯誤信息,而標準輸出更多隻是輸出提示信息。通過不同的文件描述符,把普通的提示信息和錯誤提示信息區分開,非常方便於過濾日誌。

在默認情況下,標準輸出和標準錯誤都指向同一個文件,如果在終端前臺執行,那麼不管是標準輸出還是標準錯誤,都是輸出到終端。

C語言對標準的運用

C中與這標準相關的宏有六個,

標準 stdio.h unistd.h
標準輸入 stdin STDIN_FILENO
標準輸出 stdout STDOUT_FILENO
標準錯誤 stderr STDERR_FILENO

stdinSTDIN_FILENO 都指向的是標準輸入,前者是 FILE類型,就是我們所說文件句柄,而後者是int類型,就是我們所說的文件描述符。標準輸出和標準錯誤也是一樣的情況。

所以,在不同的C接口,我們需要用不同的宏。

fprintf(stdout, "stdout\n");
write(STDOUT_FILENO, "STDOUT_FILENO\n", 14); 

前面有提到,標準輸入、標準輸出、標準錯誤是默認存在的,也就是說我們不需要open或者fopen,可以直接使用。例如

#include <stdio>

int main(int argc, char **argv)
{
    fprintf(stderr, "something error\n");
}

Shell對標準的運用

Shell命令經常用到的 重定向 實際上就是對標準的運用

標準 運用 示例
標準輸入 < cat < helloworld.c
標準輸出 > 或者 1> echo "helloworld" > stdout.log
標準錯誤 2> grep "error" 2>/dev/null

C&Shell配合

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char **argv)
{
    char input[100];
    FILE *file;

    fprintf(stdout, "stdout\n");
    fprintf(stderr, "stderr\n");
    write(STDOUT_FILENO, "STDOUT_FILENO\n", strlen("STDOUT_FILENO\n"));
    write(STDERR_FILENO, "STDERR_FILENO\n", strlen("STDERR_FILENO\n"));
}

在Bash shell中直接執行,默認情況下,標準輸出和標準錯誤都輸出到終端

[GMPY@14:43 tmp]$./stdio 
stdout
stderr
STDOUT_FILENO
STDERR_FILENO

通過Shell重定向的方法,區分開標準輸出和標準錯誤的日誌

[GMPY@14:43 tmp]$./stdio 2>stderr.log 1>stdout.log
[GMPY@14:47 tmp]$cat stderr.log 
stderr
STDERR_FILENO
[GMPY@14:47 tmp]$cat stdout.log 
STDOUT_FILENO
stdout
[GMPY@14:47 tmp]$
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章