2014年9月18日 星期四

[Linux 文章收集] Linux shell 中"2>&1"含義

Source From Here
Preface
考慮如下的 shell script:
$ nohup /mnt/Nand3/H2000G >/dev/null 2>&1 &

對於 &1 更準確的說應該是 文件描述符1 (File descriptor) ,而 1 一般代表的就是 STDOUT_FILENO,實際上這個操作就是一個 dup2(1, 2) (int dup2(int oldfd, int newfd): makes newfd be the copy of oldfd, closing newfd first if necessary. ) 調用.他標準輸出到 all_result ,然後復制標準輸出到文件描述符 2 (STDERR_FILENO), 其後果就是文件描述符1和2指向同一個文件表項,也可以說錯誤的輸出被合併了.其中 0 表示鍵盤輸入 1 表示屏幕輸出 2 表示錯誤輸出.把標准出錯重定向到標準輸出,然後扔到 /dev/null 下面去。通俗的說,就是把所有標準輸出和標准出錯都扔到垃圾桶裡面。而最后一个 &, 是让该命令在后台执行。


試想 2>1 代表什麼,2與>結合代表錯誤重定向,而1則代表錯誤重定向到一個文件1,而不代表標準輸出;換成 2>&1,&與1結合就代表標準輸出了,就變成錯誤重定向到標準輸出. 你可以用 ls 2>1 測試一下,不會報沒有2文件的錯誤,但會輸出一個空的文件1;ls xxx >out.txt 2>&1,實際上可換成 ls xxx 1>out. txt 2>&1;重定向符號 > 默認是1, 錯誤和輸出都傳到 out.txt 了.

為何 2>&1 要寫在後面?
command > file 2>&1 首先是 command > file 將標準輸出重定向到 file 中, 2>&1 是標準錯誤拷貝了標準輸出的行為,也就是同樣被重定向到 file 中,最終結果就是標準輸出和錯誤都被重定向到 file 中; 如果是 command 2>&1 >file, 則 2>&1 stderr 拷貝了stdout 的行為,但此時標準輸出還是在終端> file 後輸出才被重定向到 file但標準錯誤仍然保持在終端。用 strace 可以看到:
1. command > file 2>&1 
這個命令中實現重定向的關鍵系統調用序列是:
open(file) == 3 // Open file descriptor=3
dup2(3,1) // Change file descriptor 1=stdout to descriptor 3: 輸出到 stdout 會被導到檔案 file
dup2(1,2) // Change file descriptor 2=stderr to descriptor 1: 輸出到 stderr 會被導到 stdout, 但導到 stdout 又會被導到檔案 file.

2. command 2>&1 >file 
這個命令中實現重定向的關鍵系統調用序列是:
dup2(1,2) // Change file descriptor 2=stderr to descriptor 1=stdout: 將 stderr 導向 stdout, 而此時 stdout 會輸出到螢幕
open(file) == 3 // Open file descriptor=3
dup2(3,1) // Change file descriptor 1=stdout to descriptor 3: 將 stdout 導向檔案 file.

This message was edited 6 times. Last update was at 18/09/2014 15:18:17

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...