当前位置:K88软件开发文章中心网站服务器框架Shell → 文章内容

Shell 文件系统操作

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-23 14:39:37

由 娃娃脸呦 创建,Loen 最后一次修改 2016-02-24 前言准备了很久,找了好多天资料,还不知道应该如何动笔写:因为担心拿捏不住,所以一方面继续查找资料,一方面思考如何来写。作为《Shell编程范例》的一部分,希望它能够很好地帮助 Shell 程序员理解如何用 Shell 命令来完成和 Linux 系统关系非常大的文件系统的各种操作,希望让 Shell 程序员中对文件系统"混沌"的状态从此消失,希望文件系统以一种更为清晰的样子呈现在眼前。文件系统在 Linux 操作系统中的位置如何来认识文件系统呢?从 Shell 程序员的角度来看,文件系统就是一个用来组织各种文件的方法。但是文件系统无法独立于硬件存储设备和操作系统而存在,因此还是有必要来弄清楚硬件存储设备、分区、操作系统、逻辑卷、文件系统等各种概念之间的联系,以便理解文件系统常规操作的一些“细节”。这个联系或许(也许会有一些问题)可以通过这样一种方式来呈现:从图中可以清晰地看到各个“概念”之间的关系,它们以不同层次分布,覆盖硬件设备、系统内核空间、系统用户空间。在用户空间,用户可以不管内核如何操作具体硬件设备,仅仅使用程序员设计的各种界面就可以,而普通程序员也仅仅需要利用内核提供的各种接口(System Call)或者一些C库来和内核进行交互,而无须关心具体的实现细节。不过对于操作系统开发人员,他们需要在内核空间设计特定的数据结构来管理和组织底层的硬件设备。下面从下到上的方式(即从底层硬件开始),用工具来分析和理解图中几个重要概念。(如果有兴趣,可以先看看下面的几则资料)参考资料:从文件 I/O 看 Linux 的虚拟文件系统Linux 文件系统剖析第九章 文件系统Linux 逻辑盘卷管理 LVM 详解硬件管理和设备驱动Linux 系统通过设备驱动管理硬件设备。如果添加了新的硬件设备,那么需要编写相应的硬件驱动来管理它。对于一些常见的硬件设备,系统已经自带了相应的驱动,编译内核时,选中它们,然后编译成内核的一部分或者以模块的方式编译。如果以模块的方式编译,那么可以在系统的 /lib/modules/$(uname -r)目录下找到对应的模块文件。范例:查找设备所需的驱动文件比如,可以这样找到相应的 scsi 驱动和 usb 驱动对应的模块文件:更新系统中文件索引数据库(有点慢)$ updatedb查找 scsi 相关的驱动$ locate scsi*.ko查找 usb 相关的驱动$ locate usb*.ko这些驱动以 .ko 为后缀,在安装系统时默认编译为了模块。实际上可以把它们编译为内核的一部分,仅仅需要在编译内核时选择为[*]即可。但是,很多情况下会以模块的方式编译它们,这样可以减少内核的大小,并根据需要灵活地加载和卸载它们。下面简单地演示如何卸载模块、加载模块以及查看已加载模块的状态。可通过 /proc 文件系统的 modules 文件检查内核中已加载的各个模块的状态,也可以通过 lsmod 命令直接查看它们。$ cat /proc/modules或者$ lsmod范例:查看已经加载的设备驱动查看 scsi 和 usb 相关驱动,结果各列为模块名、模块大小、被其他模块的引用情况(引用次数、引用它们的模块)$ lsmod | egrep "scsi|usb"usbhid 29536 0hid 28928 1 usbhidusbcore 138632 4 usbhid,ehci_hcd,ohci_hcdscsi_mod 147084 4 sg,sr_mod,sd_mod,libata范例:卸载设备驱动下面卸载 usbhid 模块看看(不要卸载scsi的驱动!因为你的系统可能就跑在上面,如果确实想玩玩,卸载前记得保存数据),通过 rmmod 命令就可以实现,先切换到 Root 用户:$ sudo -s# rmmod usbhid再查看该模块的信息,已经看不到了吧$ lsmod | grep ^usbhid范例:挂载设备驱动如果有个 usb 鼠标,那么移动一下,是不是发现动不了啦?因为设备驱动都没有了,设备自然就没法用罗。不过不要紧张,既然知道原因,那么重新加载驱动就可以,下面用 insmod 把 usbhid 模块重新加载上。$ sudo -s# insmod `locate usbhid.ko`locate usbhid.ko 是为了找出 usbhid.ko 模块的路径,如果之前没有 updatedb,估计用它是找不到了,不过也可以直接到 /lib/modules 目录下用 find 把 usbhid.ko 文件找到。# insmod $(find /lib/modules -name "*usbhid.ko*" | grep `uname -r`)现在鼠标又可以用啦,不信再动一下鼠标 :-)到这里,硬件设备和设备驱动之间关系应该是比较清楚了。如果没有,那么继续下面的内容。范例:查看设备驱动对应的设备文件Linux 设备驱动关联着相应的设备文件,而设备文件则和硬件设备一一对应。这些设备文件都统一存放在系统的 /dev/ 目录下。例如,scsi 设备对应/dev/sda,/dev/sda1,/dev/sda2... 下面查看这些设备信息。$ ls -l /dev/sda*brw-rw---- 1 root disk 8, 0 2007-12-28 22:49 /dev/sdabrw-rw---- 1 root disk 8, 1 2007-12-28 22:50 /dev/sda1brw-rw---- 1 root disk 8, 3 2007-12-28 22:49 /dev/sda3brw-rw---- 1 root disk 8, 4 2007-12-28 22:49 /dev/sda4brw-rw---- 1 root disk 8, 5 2007-12-28 22:50 /dev/sda5brw-rw---- 1 root disk 8, 6 2007-12-28 22:50 /dev/sda6brw-rw---- 1 root disk 8, 7 2007-12-28 22:50 /dev/sda7brw-rw---- 1 root disk 8, 8 2007-12-28 22:50 /dev/sda8可以看到第一列第一个字符都是 b,第五列都是数字 8 。 b 表示该文件是一个块设备文件,对应地,如果是 c 则表示字符设备(例如 `/dev/ttyS0),关于块设备和字符设备的区别,可以看这里:字符设备:字符设备就是能够像字节流一样访问的设备,字符终端和串口就属于字符设备。块设备:块设备上可以容纳文件系统。与字符设备不同,在读写时,块设备每次只能传输一个或多个完整的块。在 Linux 操作系统中,应用程序可以像访问字符设备一样读写块设备(一次读取或写入任意的字节数据)。因此,块设备和字符设备的区别仅仅是在内核中对于数据的管理不同。数字 8 则是该硬件设备在内核中对应的设备编号,可以在内核的 Documentation/devices.txt 和 /proc/devices 文件中找到设备号分配情况。但是为什么同一个设备会对应不同的设备文件(/dev/sda 后面为什么还有不同的数字,而且 ls 结果中的第 6 列和它们对应起来)。这实际上是为了区分不同设备的不同部分

[1] [2] [3] [4]  下一页


Shell 文件系统操作