以前都是硬背起來的,如果要把所有的輸出都丟到 /dev/null
,要用前面的方式才會是對的,但其實在 bash 的 manpage 裡面有提到:
Note that the order of redirections is significant. For example, the command ls > dirlist 2>&1 directs both standard output and standard error to the file dirlist, while the command ls 2>&1 > dirlist directs only the standard output to file dirlist, because the standard error was duplicated from the standard output before the standard output was redirected to dirlist.
這是因為照順序跑 dup2()
的關係 (參考 bash 的 redir.c)。
前者會先把 dirlist
開起來後透過 dup2()
複製到 fd=1,再用一次 dup2()
把 fd=1 複製到 fd=2,達到我們要的效果。
後者則是先把 fd=1 複製到 fd=2 (於是大家都丟到 stdout 了),接下來再把 dirlist
開起來,丟到 fd=1。這樣變成 ls
寫到 stderr 的東西變成到 stdout 了,而本來寫到 stdout 的東西進到 dirlist
這個檔案裡。
剛剛寫 code 時想找一下有沒有官方文件或是 source code 有描述 ordering 或是有定義行為,結果發現 bash 的 manpage 裡面就有提到了...