本文並不是闡述文件描述符與文件句柄的異同,而是標準
shell
fork
建立一個進程,規定默認存在3個文件描述符,分別是bash
描述符編號 | 簡介 | 做用 |
---|---|---|
0 | 標準輸入 | 通用於獲取輸入的文件描述符 |
1 | 標準輸出 | 通用輸出普通訊息的文件描述符 |
2 | 標準錯誤 | 通用輸出錯誤信息的文件描述符 |
標準輸入比較好理解,在函數scanf
中,就是從標準輸入獲取的數據。咱們執行一個命令,只要此命令在前臺執行,標準輸入就是咱們在終端的輸入。函數
標準輸出與標準錯誤用途是有差異的。從命名上咱們就發現,標準錯誤用於輸出錯誤信息,而標準輸出更多隻是輸出提示信息。經過不一樣的文件描述符,把普通的提示信息和錯誤提示信息區分開,很是方便於過濾日誌。日誌
在默認狀況下,標準輸出和標準錯誤都指向同一個文件,若是在終端前臺執行,那麼無論是標準輸出仍是標準錯誤,都是輸出到終端。code
C中與這標準相關的宏有六個,blog
標準 | stdio.h | unistd.h |
---|---|---|
標準輸入 | stdin | STDIN_FILENO |
標準輸出 | stdout | STDOUT_FILENO |
標準錯誤 | stderr | STDERR_FILENO |
stdin
和 STDIN_FILENO
都指向的是標準輸入,前者是 FILE
類型,就是咱們所說文件句柄,然後者是int
類型,就是咱們所說的文件描述符。標準輸出和標準錯誤也是同樣的狀況。接口
因此,在不一樣的C接口,咱們須要用不一樣的宏。進程
fprintf(stdout, "stdout\n"); write(STDOUT_FILENO, "STDOUT_FILENO\n", 14);
前面有提到,標準輸入、標準輸出、標準錯誤是默認存在的,也就是說咱們不須要open
或者fopen
,能夠直接使用。例如input
#include <stdio> int main(int argc, char **argv) { fprintf(stderr, "something error\n"); }
Shell命令常常用到的 重定向 實際上就是對標準的運用string
標準 | 運用 | 示例 |
---|---|---|
標準輸入 | < | cat < helloworld.c |
標準輸出 | > 或者 1> | echo "helloworld" > stdout.log |
標準錯誤 | 2> | grep "error" 2>/dev/null |
#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]$