Unix 系列(Linux、BSD...) 的 STDIN、STDOUT、STDERR 是輸入、輸出串流... 等等, 已經玩了N年, 但是看了 $4 長輩的這篇文章: 關於 Bash 的 Redirection 使用的心得, 寫得很清楚, 但是看到最後反而覺得有點頭大(stdout連3都用到了), 搭配簡單的程式重新複習一下~
STDIN、STDOUT、STDERR 說明
先把 STDIN、STDOUT、STDERR 的基本東西整理一下~
- 0: stdin (Standard input) 標準輸入串流 (鍵盤輸入)
- 1: stdout (Standard output) 標準輸出串流 (輸出於 Cli 視窗)
- 2: stderr (Standard error) 標準錯誤輸出串流 (輸出於 Cli 視窗)
簡單易懂的圖片可見(取自: Standard streams - Wikipedia, the free encyclopedia):
下述摘錄自此篇: linux - confused about stdin, stdout and stderr? - Stack Overflow
- stdin
- Reads input through the console(eg Keyboard input) Used in C with scanf
- scanf(<formatstring>,<pointer to storage> ...);
- 註: scanf() = fprintf(stdin, "...");
- stdout
- Produces output to the console Used in C with printf
- printf(<string>, <values to print> ...);
- 註: printf() = fprintf(stdout, "...");
- stderr
- Produces 'error' output to the console Used in C with fprintf
- fprintf(stderr, <string>, <values to print> ...);
STDIN、STDOUT、STDERR 測試
用簡單的程式來測試看看 STDOUT、STDERR (STDIN 在此就先不管了).
- $ vim stdtest.c
#include <stdio.h> int main() { // 將輸出、輸入、標準錯誤都寫到指定檔案 //freopen("./stdin.log", "w", stdin); //freopen("./stdout.log", "w", stdout); //freopen("./stderr.log", "w", stderr); fprintf(stdin, "This is stdin\n"); // 等同 scanf("..."); fprintf(stdout, "This is stdout\n"); // 等同 printf("..."); fprintf(stderr, "This is stderr\n"); // 會印在螢幕上, 但是不會進入 輸出導向 裡面. return 0; }
- $ gcc -o stdtest ./stdtest.c # stdin 在下面測試看不出任何東西 (因為沒有任何輸入)
- $ ./stdtest # stdout、stderr 都會印在螢幕上
This is stdout
This is stderr - $ ./stdtest > std.log # 預設導向會將 stdout 導入檔案, stderr 會印於螢幕
This is stderr
- $ cat std.log # 檔案裡面只有 stdout 的內容
This is stdout
- $ ./stdtest > std.log 2>&1 # 將輸出、錯誤 全部導到 std.log (螢幕沒任何輸出)
- $ cat std.log # 檔案裡面有 stdout、stderr
This is stderr
This is stdout
相關網頁
- 標準串流 - 維基百科,自由的百科全書
- Linux Shell I/O redirect
- BASH Programming - Introduction HOW-TO: All about redirection
- STDIN, STDOUT, STDERR
有没有这三个文件指针的具体说明呢?感觉基本的定义还不清楚。
這... 已經很清楚了耶.. Orz..
您好,
想請問一下2>&1的意思
而其中的&是什麼意思呢?
謝謝
好問題, 我也不知道耶.
我把它想成是 reference 的意思, 如果您有查到正確的答案, 也在麻煩您指點一下~ 謝謝. 🙂
& 的意思就是 把 错误日志 “ 2 ” 重定向 到 普通日志 的 “ 1 ”
你可以理解成,因为 “ 1 ” 是一个特殊处理的符号,
所以你必须要在 “1 ” 前面加一个 “ & ” 才可以重定向过去 。
否则就是重定向到一个 名字为 “ 1 ” 的文本文件了。