第4章 文件系统:编写pwd

本文深入探讨了Unix/Linux文件系统的结构,包括目录树、文件的存储和i-节点等概念。通过实验了解了mkdir、rmdir、mv和ln命令的用法。特别地,讨论了硬链接如何工作,以及如何通过i-节点查找目录位置。文章还介绍了创建文件时系统内部发生的过程,并详细解释了cat命令的工作原理。最后,阐述了如何编写pwd命令,通过追踪.的i-节点来确定当前目录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

这段时间毕业、工作入职占用了大量时间,很久没有跟进了,现在在公司培训了,希望自己的未来会更好!!

这章主题跟文件目录相关,pwd命令就是能输出现在所处在的目录的路径

4.1 概念

文件包含数据,而目录是文件的列表。而pwd命令则可以显示出你在目录中的位置。

要编写pwd命令必须要了解文件和目录是如何组织和存储的。首先查看文件系统的外在特征,再分析内部结构,最后学习相应的系统调用的功能和使用方法。

4.2 从用户刊文件系统

硬盘中的文件组成一颗目录树,如图所示:

跟着书中的实验,了解相关命令的结果:

实验中可以了解mkdir创建、rmdir删除目录,mv可以用于重命名;

第二个实验比第一个复杂,作者故意绕的,结果如图:

在实验中ln命令是建立了一个硬链接,相当于是源文件的副本,但是不占用额外的空间,对其操作会直接影响源文件中的内容。

 实验中x和xlink都是链接,链接是指向文件的一个指针。

文中还介绍了其他的命令,可以自行练习。 

目录树的深度几乎没有限制,但是,有可能所建的目录树太深以置超过许多命令允许的范围。我已经创建了测试代码并bash运行了

输入ls -R后会出现目录名称太长显示不出

尴尬的是我看错了,我输入rm -rf deep-well后删除了文件,如果rm -r不能删除的答案就是rm -rf

4.3 文件系统的内部结构

第一层抽象:磁盘->分区

第二层抽象:磁盘->块序列

扇区是磁盘的基本存储单元

第三层:从块序列到三个区域的划分

文件系统可以用来存储文件内容、文件属性和目录,unix使用简单的方法将磁盘分为三部分

数据区:用于存放文件内容;

i-节点表:用于存放文件属性

超级块:用于存放文件系统本身的信息

其中任一部分都是很多有序磁盘块组成。

文件系统的实现

创建一个文件会发生什么?

在命令行输入who > userlist

 会新建一个文件userlist,文件创建必然存放在磁盘中,所以u文件系统必然发生改变,在创建、删除文件时文件系统三个部分必然发生,如图:

创建文件的4个主要操作:

1、存储属性:内核先找到一个空的i-节点,将文件属性记录

2、存储数据:假设新文件需要3个存储块,内核则会从自由块列表找出3个自由块,将数据存放在这3个数据块中

3、记录分配情况

4、将文件名添加到目录

目录的工作过程  

目录是一种包含了文件名字列表的特殊文件,一个包含i-节点号和文件名的表,使用ls -1ia(是数字1,不是l)(-i是输出i-节点号,1意思是每行列出一个文件)

可以看到第一列是i-节点号.

书中的下个例子没有,我自己弄了个,链接文件的i-节点号是一样的

 cat命令的工作原理

输入cat userlist,会发生什么

1、在目录中寻找文件名,找到i-节点号

2、定位i-节点并读取他的内容,内容中有数据块编号的列表

3、访问存储文件内容的数据块

而大文件的话,无法记录那么多的编号,则使用间接块的方法,详细的读写逻辑算法这边还不用纠结,大概方法如图(文中有比较详细的创建间接块的解释):

4.4理解目录

对于用户,目录是文件名的列表,对于unix系统则是被命名的指针的列表

 

 

 

 4.5编写pwd

pwd命令可以知道本目录地址,根据上面的知识我们也应该知道,现目录就是"."的i-节点,必然通过这个i-节点继续向上追溯,直到树顶

 

(1)得到"."的i-节点号,称为n

(2)使用chdir ..

(3)利用n号找到名字,存储(使用opendi、readdir、closedir)

(4)重复直到树顶

又因为树顶的"."和".."指向自身,判断"."和".."的i-节点值相同代表树顶;要么迭代方式一一存放目录名,但是操作麻烦,可以使用递归直接打印目录名称。

我自己编写了个pwd,跟书上代码有点不一样,逻辑差不多,以上传gitee,多使用man命令,很有用

 

<think>好的,我现在要解决用户在Windows上运行Python脚本时遇到的ModuleNotFoundError: No module named 'pwd'错误。根据提供的引用资料,我需要先理解问题出现的原因。 首先,引用[3]提到pwd模块是Unix系统专用的,用于访问密码数据库,而Windows上没有这个模块。因此,当用户尝试在Windows上运行依赖pwd的代码时,就会报错。这个问题通常出现在跨平台项目中,尤其是当代码原本是为Unix系统编写的时候。 接下来,我需要考虑解决方案。引用[3]和[4]给出了几种方法。可能的解决途径包括:修改代码以移除对pwd的依赖,或者使用Windows兼容的替代方法。例如,引用[4]提到可以定义一个替代的struct_passwd类,并使用getpass模块来获取用户名,这可能是一个可行的方案。 另外,用户的问题涉及Langchain-Chatchat项目中的init_database.py脚本。根据引用[3],错误发生在导入pebblo.py模块时,该模块试图导入pwd。因此,可能需要修改该文件的代码,替换掉pwd模块的调用部分。 可能的步骤包括:定位到引发错误的pebblo.py文件,找到使用pwd的地方,将其替换为Windows兼容的代码。例如,使用os模块或getpass来获取用户信息。例如,用getpass.getuser()替代pwd.getpwuid(os.getuid()).pw_name。 同时,用户可能需要检查是否有其他部分也依赖pwd模块,并逐一修改。或者,如果该模块在Windows环境下并非必需,是否可以禁用相关功能? 另外,引用[2]提到的模块导入问题可能与项目结构有关,但当前问题更直接的是pwd模块缺失,因此重点应放在替代方案上。 总结可能的解决方案: 1. 修改源代码,替换pwd模块的相关代码为Windows兼容的方法。 2. 使用兼容层或补丁代码,例如在代码中模拟pwd模块的存在。 3. 检查是否有更新版本的库,可能该问题在后续版本中已修复。 需要确保用户在修改代码后,重新运行脚本时不会再次遇到同样的错误。此外,可能需要指导用户如何找到并修改相关文件,或者建议他们向项目维护者反馈此问题,以便未来版本支持Windows环境。</think>根据引用内容分析,Windows系统缺少Unix专用模块$pwd$导致报错,可通过以下步骤解决: ### 解决方案 1. **定位错误文件** 根据引用[3]的报错路径,找到文件`pebblo.py`,路径通常为: ``` ...\Lib\site-packages\langchain_community\document_loaders\pebblo.py ``` 2. **修改代码兼容Windows** 打开`pebblo.py`,将第6行附近涉及$pwd$的代码: ```python import pwd user = pwd.getpwuid(os.getuid()).pw_name # 原Unix代码 ``` 替换为Windows兼容方案(引用[4]): ```python import getpass, os class struct_passwd: # 定义替代类 def __init__(self, pw_name): self.pw_name = pw_name def getpwuid(uid): # 定义替代函数 return struct_passwd(getpass.getuser()) user = getpwuid(os.getuid()).pw_name # 修改后代码 ``` 3. **验证运行环境** 确保Python版本≥3.6,并重新安装依赖: ```bash pip install -r requirements.txt --upgrade ``` ### 替代方案 - **临时屏蔽功能**:若无需相关功能,可直接注释掉报错代码段 - **虚拟机/Linux子系统**:通过WSL运行项目(长期推荐方案)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值