You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu中open-file-description table与Tanenbaum描述不符?Shell脚本文件写入测试问题求助

问题核心:混淆了「独立进程打开文件」和「共享打开文件描述符」的场景

这是个非常典型的场景误解——你测试的脚本和Tanenbaum在《现代操作系统》里描述的根本不是同一个文件操作场景,Ubuntu(基于Linux内核)的实现完全符合书中的理论,只是你的脚本没有触发「共享打开文件描述符(OFD)」的条件。

先明确书中的场景到底是什么

Tanenbaum提到的“p1和p2使用同一个open-file-description table”,指的是两个进程共享同一个内核级别的打开文件描述(OFD)——这种情况只会发生在:

  • 一个进程打开文件后,通过fork()创建子进程,子进程会继承父进程的文件描述符,此时父子进程的文件描述符指向同一个OFD;
  • 同一进程内通过dup()/dup2()复制文件描述符,或者用特定打开标志复用已有的OFD。

在这种共享OFD的场景下,OFD中记录的文件偏移量是全局共享的——p1写入后移动了偏移量,p2会接着这个位置继续写入,不会覆盖之前的内容。

你的脚本为什么会覆盖?

你写的脚本里,echo 11 > a.txt和echo 12 > a.txt是两个完全独立的进程:

  1. 第一个echo进程启动时,shell会帮它执行open("a.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666)——这里的O_TRUNC标志会直接把文件长度截断为0,然后写入"11\n",接着关闭文件;
  2. 第二个echo进程启动时,同样会执行带O_TRUNC的打开操作,再次清空文件,写入"12\n"后关闭。

本质上是两个进程分别打开、截断、写入、关闭文件,完全没有共享任何OFD,自然会出现覆盖的结果。

如何验证书中的描述?

我们可以写一个真正触发共享OFD的脚本,比如让两个子进程继承父进程打开的文件描述符:

#!/bin/bash
# 打开a.txt,分配文件描述符3,使用读写模式且不截断文件(如果文件存在则保留内容)
exec 3<> a.txt

# 启动两个子进程,它们会继承文件描述符3,共享同一个OFD
(echo "来自p1的内容" >&3) &
(echo "来自p2的内容" >&3) &

# 等待两个子进程执行完成
wait

# 关闭文件描述符3
exec 3>&-

运行这个脚本后,打开a.txt会看到两个进程的内容都被写入(顺序可能因为进程调度略有不同,但绝对不会互相覆盖)——这就是Tanenbaum书中描述的场景。

总结

Linux内核(包括Ubuntu)的文件系统实现完全符合POSIX标准,也和Tanenbaum的理论一致。你的测试脚本只是没有命中「共享OFD」的场景,才会出现和预期不符的结果。

内容的提问来源于stack exchange,提问作者Phi Quang Phuoc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 07:52:42