ลองดูโค้ดตัวอย่างก่อน:
#include <stdio.h>
main()
{
// message 1, on stdout (using printf)
printf("%s", "message 1, on stdout (using printf)\n");
// message 2, on stdout (using fprintf)
fprintf(stdout, "%s", "message 2, on stdout (using fprintf)\n");
// message 3, on stderr (using fprintf)
fprintf(stderr, "%s", "message 3, on stderr (using fprintf)\n");
}
ให้เปรียบเทียบผลลัพธ์:
./helloerror
+ ไฟล์: ไม่มีข้อความ คอนโซล: ข้อความ 1,2,3;
./helloerror >error.txt
+ ไฟล์: ข้อความ 1,2; คอนโซล: ข้อความ 3;
./helloerror 2>&1 >error.txt
+ ไฟล์: ข้อความ 1,2; คอนโซล: ข้อความ 3;
+ เช่นเดียวกับ. /helloerror> error.txt
./helloerror >error.txt 2>&1
+ ไฟล์: ข้อความ 3,1,2; คอนโซล: ไม่มีข้อความ;
+ สังเกตคำสั่งที่ 3 เป็นลำดับแรกจากนั้น 1 จากนั้น 2
./helloerror | tee error.txt 2>&1
+ ไฟล์: ข้อความ 1,2; คอนโซล: ข้อความ 3,1,2;
+ สังเกตคำสั่งที่ 3 เป็นลำดับแรกจากนั้น 1 จากนั้น 2
./helloerror 2>&1 | tee error.txt
+ ไฟล์: ข้อความ 3,1,2; คอนโซล: ข้อความ 3,1,2;
วิธีใช้:
./helloerror >error.txt 2>&1
-> หากต้องการข้อความทั้งหมด (stdout + stderr) ในไฟล์ แต่ไม่ได้พิมพ์บนคอนโซล
./helloerror 2>&1 | tee error.txt
-> หากต้องการข้อความ (stdout + stderr) ทั้งหมดในไฟล์และพิมพ์บนคอนโซล
utility 2>&1 | tee output.log
คุณหมายถึงว่าตั้งแต่ 1 กำลังถูกนำไปยัง tee, 2 เช่นกันเนื่องจาก tee ซ้ำกับสตรีมเอาต์พุตจะแสดงทั้งบนคอนโซลและเขียนลงในไฟล์ดังนั้นความแตกต่างระหว่างutility 2>&1 > output.log
และutility 2>&1 | tee output.log
อยู่tee
ในนั้นซ้ำกับกระแสนั้นจะถูกต้องหรือไม่