Bash
重定向標準輸出和錯誤時,在沒有 >> 的情況下附加作品
我有一個文件
test.txt
,但沒有名為test
. 當我嘗試ls test test.txt > new 2>new
我期待
new
被覆蓋,因為>>
沒有使用。但是在輸出文件中,我附加了兩個內容。為什麼會這樣?
TL;DR
bash
在寫入任何內容之前打開並截斷所有涉及的文件。stdout
並且stderr
都被發送到,new
因為在開始列印bash
時已經截斷了文件(兩次) 。ls
這就是
bash
準備/處理 I/O 重定向的方式。當您要求將命令重定向(>
)到文件時,bash
基本上會打開該文件,並在必要時創建它。如果文件已存在,則將其截斷。在您的情況下,這是通過open
系統呼叫和一些標誌來完成的:open("new", O_WRONLY|O_CREAT|O_TRUNC, 0666)
O_CREAT
如果文件不存在則創建該文件,如果存在則O_TRUNC
截斷該文件。此open
系統呼叫是bash
重定向初始化的一部分,這意味著當您使用多個重定向操作時,例如在…$ ls test test.txt > new 2>new
…
bash
首先打開所有相關文件。因此,在執行之前ls
,它會打開new
兩次,使用相同的標誌:open("new", O_WRONLY|O_CREAT|O_TRUNC, 0666) open("new", O_WRONLY|O_CREAT|O_TRUNC, 0666)
這意味著基本上,在執行您的命令時,
bash
執行以下操作(按此順序):
- 作為標準輸出打開
new
,必要時創建/截斷文件。- 作為標準錯誤打開
new
,必要時創建/截斷文件。- 執行
ls
:這會將內容寫入new
.如您所見,在開始之前
bash
截斷所有涉及的文件。這意味著當使用 , 執行某些東西時,基本上被截斷“兩次”,然後,輸出被重定向到它。您期望的行為需要獨立擷取’s stdout 和 stderr ,並在寫入之前一個接一個地打開它們。基本上:ls``... >new 2>new``new``bash``ls
- 開始
ls
。- 當有事情發生時
stdout
,打開new
,截斷它並寫入它。- 當某些事情發生時
stderr
,再次打開new
,截斷它,然後寫入它。但是,消息可能會交織在一起:重定向的程序很可能會向 寫入一些內容,
stdout
然後向.行為…)。stderr``stdout