我使用终端将多个命令的输出同时传输到同一个文件中,如下所示:
cmd1 | tee -a /tmp/file
cmd2 | tee -a /tmp/file
cmd3 | tee -a /tmp/file
使用安全吗?此方法是否存在数据丢失或读/写权限问题?
编辑:我对输出混合感到满意,我只是想确保所有内容都写入文件。如果两个命令尝试同时将输出写入文件怎么办,它会崩溃吗?
答案1
如果您将 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()
无论是哪个实例,每次调用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.