Bash

使用 tee 同時將多個命令輸出通過管道傳輸到同一個文件是否安全?

  • September 20, 2020

我使用這樣的終端同時將多個命令的輸出通過管道傳輸到同一個文件中:

cmd1 | tee -a /tmp/file
cmd2 | tee -a /tmp/file
cmd3 | tee -a /tmp/file

使用安全嗎?此方法有任何數據失去或讀/寫權限問題嗎?

編輯:我對混合輸出很好,我只想確保所有內容都寫入文件。如果兩個命令試圖在同一時間將輸出寫入文件怎麼辦,它會崩潰嗎?

如果您將 tee 與append( -a) 模式一起使用,則不會有數據失去的風險,但沒有附加操作的文件系統(例如 NFS)除外。在append模式下,tee打開帶有O_APPEND標誌的文件。

$ echo 1 | strace tee -a /tmp/file 2>&1 | grep open | grep /tmp/file
openat(AT_FDCWD, "/tmp/file", O_WRONLY|O_CREAT|O_APPEND, 0666) = 3

來自man 2 openat

O_APPEND
     The file is opened in append mode.  Before each write(2), the
     file offset is positioned at the end of the file, as if with
     lseek(2).  The modification of the file offset and the write
     operation are performed as a single atomic step.

關鍵語句是文件偏移量的修改和寫入操作作為單個原子步驟執行。每次呼叫write()from 的任何一個實例tee都保證原子地將文件偏移量定位到文件末尾,然後寫入數據。

手冊頁確實注意到這種openat使用模式在 NFS 文件系統上是不安全的(正如我之前提到的):

     O_APPEND may lead to corrupted files on NFS filesystems if more
     than one process appends data to a file at once.  This is be‐
     cause  NFS does not support appending to a file, so the client
     kernel has to simulate it, which can't be done without a race
     condition.

引用自:https://unix.stackexchange.com/questions/610329