為什麼不同的重定向方式指令執行時長會有差異?

為什麼不同的重定向方式指令執行時長會有差異?

我正在find以普通用戶身份運行定時命令。

我所知道的是,重定向是為了防止終端上出現 stdout/stderr 訊息。如果是這樣,為什麼不同的重定向方法需要不同的時間?它是否與 tty 上的寫入速度有關,或者背後是否有其他原因?有人能指出我理解這一點的正確方向嗎?

$ id
uid=1000(user1) gid=1000(user1) groups=1000(user1),1001(user2)

$time find /
<truncated output>
real    0m13.902s
user    0m0.197s
sys 0m0.448s

$ time find /  >/dev/null  
<truncated output>
real    0m0.298s
user    0m0.068s
sys 0m0.206s

$time find /  2> /dev/null 
<truncated output>
real    0m13.279s
user    0m0.181s
sys 0m0.405s

$ time find /  > /dev/null 2>&1
real    0m0.306s
user    0m0.109s
sys 0m0.174s

答案1

當您的進程 ( find) 需要實際寫出輸出時,這顯然比您告訴它丟棄所述輸出所花費的時間要長得多。

  • 當您使用 時find /,stdout 和 stderr 都會傳送到您的終端,並且它必須寫出它們(即實際結果和所有權限錯誤等等)

  • 當您使用時,time find / >/dev/null您將刪除命令的標準輸出,但仍然會列印所有錯誤(如果有的話)。從您的結果來看,您有很多合法的結果,並且錯誤很少。

  • 當您使用 時time find / 2> /dev/null,命令的標準輸出仍會傳送到您的終端,但現在您只需刪除 stderr。如果您透過檔案系統發現您無權讀取,這實際上會非常快。

  • 當您使用 時time find / > /dev/null 2>&1,您將刪除標準輸出,然後將標準錯誤傳送到傳送標準輸出的位置,...即,您將刪除兩者。這不會輸出任何內容,因此將是所有命令中最快的。

答案2

我所知道的是,重定向是為了防止終端上出現 stdout/stderr 訊息。

好吧,不:您也可以重定向到文件:

find / > ~/all-the-files

它與 tty 上的寫入速度有某種關係嗎?

總之,是的。

無論您使用哪種終端(Linux 中的虛擬控制台、本地 xterm、透過 SSH 連接的終端),實際的終端模擬器都必須繪製終端上列印的所有內容,即使在這種情況下它會滾動快出來了。 (這裡的連接mosh可能是例外。)

透過網路連接,還需要考慮傳輸延遲,有些數據可能會被緩衝,如果有很多數據,而不是全部。如果您將某些內容重新導向到/dev/null,它不會保存在任何地方,也不會繪製。對於中等數量的數據,重定向到檔案也會很快,因為作業系統可能會將寫入內容快取在記憶體中,然後才實際延遲寫入磁碟。對於大量數據,寫入磁碟也可能成為瓶頸。 (或者,如果您設法讓進程以同步 I/O 模式寫入輸出)

對於執行大量輸出的程序,printf()即使資料被重定向到/dev/null.在這種情況下,如果您可以說服程式完全禁止輸出,速度可能會更快。這可能不是 的情況find,我認為它會受到 I/O 速度或系統呼叫開銷的限制。

另請注意,如果您find重複在同一目錄樹中運行,第一次可能會比其他次慢,因為第一次可能需要從磁碟讀取,而之後,大部分資料將被作業系統快取。

相關內容