本文翻译自BlackBerry官方提供的QNX® Neutrino® RTOS User’s Guide仅供学习参考使用第五章 文件操作文章目录第五章 文件操作文件类型文件名和路径名绝对路径和相对路径点和点点目录没有硬盘字母以点开头的路径名扩展名路径空间映射文件名规则所有内容的存储位置/bin/dev/etc/homelib/proc/root/sbin/tmp/usr/var用户所有权和权限Setuid 和 setgid粘滞位默认文件权限访问控制列表ACLs文件扩展名故障排查在QNX Neutrino 系统中几乎一切都是文件。设备、数据甚至服务通常都用文件来表示。这让你可以轻松地从本地或者远程通过命令行或程序来对文件进行操作。本章聚焦在防断电文件系统(fs-qnx6.so)中文件的相关操作。防断电文件系统是QNX Neutrino RTOS系统中的默认文件系统。更多信息请参考文件系统操作章节文件类型QNX Neutrino 支持多种文件类型。文件类型能让你大致了解文件包含什么类型的数据以及你应预期文件会如何表现。ls -l 指令中如下括号中的字符代表了文件类型常规(-)一个包含了用户数据的文件例如C代码、HTML、数据。例如/home/fred/myprog.c目录d一个目录下包含了文件和其他目录例如/home/fred符号链接l文件或目录的别名例如/usr/bin/more是/usr/bin/less的符号链接。更多信息请参考文件系统操作章节中的“链接与索引”。特殊命名n其他类型文件的行为和内容不适用于特殊用途文件。例如/proc/dumper 表示应用程序崩溃时生成核心转储core dump的钩子/dev/random 表示随机数的来源。字符特殊文件c代表字符设备的条目。例如/dev/ser1 代表一个串口**FIFO特殊文件p代表两个程序间通讯的命名管线。例如PipeA块特殊文件b代表块设备如磁盘的条目。例如/dev/hd0代表你的基础硬盘驱动的原始数据块Socket 文件s代表通讯socket的条目特别是Unix域的socket。更多信息请参考QNX Neutrino C库指南中的socket()接口一些文件在系统一次启动时会一直存在例如觉大多是文件和磁盘文件系统。其他文件只存在于管理它们的程序正在运行时。例如内存共享对象、/proc 文件系统中的对象以及磁盘上仍在被访问的临时文件尽管指向这些文件的链接即它们的文件名已被删除。文件名和路径名要访问任何文件或目录你需要提供一个路径名——这是一个符号名称用于告诉程序该文件在从根目录 / 派生出的目录树中的具体位置。一个典型的QNX Neutrino路径名看起来如下/home/fred/.profile在这个例子中.profile可以在fred目录下被找到而fred 又在home目录下home又在/即根目录下和Linux与其他Unix类似操作系统一样QNX Neutrinol路径元素是以斜杠/来分隔的。而不是像Microsoft系统中用反斜杠\来分隔的。使用ls指令来浏览你系统中的文件和目录。这个指令和MS-MOS中的dir是一样的。更多信息请参考使用命令行章节的基础目录部分。或命令指南中的ls部分绝对路径和相对路径有两种路径类型绝对路径以斜杠/开头的路径名。他是相对根目录的例如/home/fred/my_apps/favs.相对路径不以斜杠/开头的路径名代表了相对你当前工作目录的位置。例如你当前的目录是/home/fred一个 相对路径my_apps/favs和绝对路径/home/fred/my_apps/favs是等价的你不能通过路径名判断它是一个目录、一个文件、一个符号链接还是其他文件类型。判断文件类型需要通过file指令或ls -ld指令。但一个特例是如果一个路径名以/结尾它永远代表一个目录。如果你在ls指令上使用-F选项它会在目录名后显示/。点和点点目录大多数目录包含两个特殊链接.(点和…(点点.(点当前目录…(点点当前目录所在的目录即其父目录。因此例如你要列出你当前工作目录上一层目录的所有内容你可以输入ls..如果你当前目录是/home/fred/my_apps/favs,你可以输入ls../../../..来列出根目录下所有内容然后绝对路径(/)更加简洁你也不用数你需要多少个“点点”没有硬盘字母和Microsoft Windows中用路径前的字母例如C:\代表硬盘不同QNX Neutrino 用路径中的常规目录代表硬盘驱动。访问另一文件系统的目录被称为挂载点例如在第二块硬盘上的分区。一般基础的基于此判断文件系统是被挂在到/根目录。一个完整的QNX Neutrino 将所有其他测盘路径自动挂在/fs路径下例如因此在基于DOS的系统中你或许可以通过D:\访问你硬盘的第二分区而在QNX Neutrino系统中你或许需要通过/fs/hd0-qnx6-2来访问防断电文件系统第二分区。更多关于QNX Neutrino系统中典型的路径名的信息请参考本章中“所有内容的存储位置”。更多关于挂在文件系统的内容请参考文件系统操作章节。以点开头的路径名当你使用ls指令列举目录下的内容是以英文句号.开头的目录通常会被隐藏。程序通常会在配置文件或目录名称前加上一个英文句号以将其隐藏起来。这些文件并不令人以外地被称之为隐藏文件。除了被ls和一些其他程序特殊处理外这些隐藏文件并没有什么特别的。使用ls -a可以列出包括隐藏文件的所有文件。扩展名文件名扩这文件名后的.xx用于告知程序和用户该文件包含的数据类型。在QNX Neutrino文件系统中扩展名只是文件名普通的一部分只要文件名在505 字节的大小限制内扩展名可以是任何长度。大多数时候文件扩展名只是简单的命名规范但有些工具会根据文件扩展名来决定其行为。QNX Neutrino系统中常见的扩展名列表请参考“文件扩展名”一节路径空间映射你可能已经注意到我们之前说到的文件和目录是显示在它的父目录下而不是说父目录包含了这些文件。这是因为QNX Neutrino系统中路径空间是虚拟的这是因为在 QNX Neutrino 中路径名空间是虚拟的——它不仅由挂载在根目录下的介质上的文件系统决定还由进程管理器所注册的路径及路径别名共同决定。例如我们拿路径名空间中的一小部分来看。在一个典型的基于磁盘的QNX Neutrino系统中目录 / 映射到物理硬盘分区上文件系统的根目录。而这个文件系统并不真的包含/dev目录这个目录是通过进程管理器的接管而虚拟存在的。而后文件名ser1也不是真实存在的它是由串口驱动接管的。因此可以创建虚拟路径组合即组合文件系统。这种情况发生在多个资源管理器接管路径空间中同一目录下的文件时。哪个资源管理器管理管理哪个文件或目录是基于路径名映射以及底层文件系统挂在顺序这在《系统架构指南》进程管理器章节称作“路径名管理”。组合中文件系统越多事情就会变得越复杂。从创建可维护的系统的角度我们建议你越少创建目录组合约好。文件名规则QNX Neutrino 支持多种文件系统每种文件系统对合法文件名有不同的能力和规则。关于文件系统的能力请参考文件系统操作章节关于文件系统的限制请参考理解系统限制章节。文件名的最大长度是视文件系统而定的。文件名中的字符可以是除了以下特例以外的任何值以下均以十六进制表示0x00 到 0x1F (全部控制字符)0x2F (/)0x7F (擦除)0xFF如果你正在使用 Unicode 字符的 UTF-8 表示形式来表示国际字符,那么文件名的长度限制会变得更低取决于你所用到的文字的扩展范围。在防断电文件系统文件系统中你可以通过 UTF-8对Unicode 字符进行编码来使用国际字符。包含UTF-8的字符在命令行中一般无法正确显示。你也可以用ISO-Latin1补充包和PC上的字符包来表示国际字符。但是这些8-bit字符的显示是由你终端的显示设置决定的。其他操作系统通过网络访问时它们可能和你预期的显示不同。包括Microsoft Windows在内的大部分其他操作系统支持UTF-8/Unicode字符。实际上老版本的Microsoft Windows中的文件名可能使用了多语言的代码页来编码8-bit字符。QNX Neutrino系统中的DOS文件系统可以翻译这些UTF-8表达但是你需要通过命令行告诉文件系统使用哪个代码页。我们的文件系统——也就是fs-dos.so, fs-ext2.so,防断电文件系统( (fs-qnx6.so), 以及fs-udf.so都使用UTF-8编码来表示文件名。在这些文件系统中尝试使用非UTF-8编码作为文件名会失败报错EILSEQ所有内容的存储位置QNX Neutrino 操作系统并不规定具体的文件系统层级分布系统设计者一般可以自由地组织文件以适用系统的目标。例如依据传统UNIX文件系统布局或许会有利于一个由通用开元组件构建的多用户系统查阅http://www.pathname.com。另一方面一个安全的嵌入式系统可能更适合采用一种避免联合路径即任何由多个资源管理器提供服务的路径的布局并且其中的某些文件被限制为只读、已验证且可能加密的文件系统。QNX Neutrino 系统中的文件布局主要由以下因素决定每个资源管理器的挂载点一般被查工作“附载点”每个文件在资源管理器中的相对路径文件系统资源管理器包括提供主映像文件系统 IFS的资源管理器都可以挂载到路径空间中的任意位置。IFS 默认挂载在 /并为 IFS 中的所有对象添加 proc/boot 前缀。这造成了以/proc/boot开头的任何文件永远都会先查询到procfs(/proc 资源管理器这会轻微影响性能。你可以通过mkifs 构造文件中送[prefix“”] 和 [mount“/ifs”]选项来挂在IFS到/ifs 来避免这个问题。当你正在填充一个可以被挂在在任何位置的文件系统时应避免绝对路径和系统挂载位置的假设。例如防断电文件系统中的路径lib/libfoo.so,当系统被挂在路径空间的根目录时会变成/lib/libfoo.so而被挂载在/fs/qnx6时会变成/fs/qnx6/lib/libfoo.so。系统中请求这一路径的路径管理器会被路由到正确的资源管理器。很多针对设备的资源管理器和文件系统资源管理器不同会把他们的挂载点硬编码典型的会在/dev下。但这一般并不是强制要求如果你发现你的设备管理器和你系统的布局有冲突你或许会希望和资源管理器的提供商联系并让他们更改。或者更好的允许你使用命令行指定挂载点。然而也有很少一部分路径是必须要存在在QNX Neutrino 系统中。/usr/lib/ldqnx.so.2 or /usr/lib/ldqnx-64.so.2实时连接器也叫动态连接器。在所有QNX Neutrino 操作系统中这个路径都是硬编码的/.boot (仅x86_64)存放基于BIOS的系统所需要的所有IFS二进制文件的目录。本章节的其余部分将描述QNX Neutrino 版本的传统UNIX布局。/binbin目录包含了基础指令的二进制文件例如 chmod、ls以及ksh在命令行中输入 “use 指令名”来显示基础指令的语法。更多信息请参考《指令指南》/dev/dev目录诗雨资源管理器它包含了设备文件可能包含了/dev/cdnCD-ROM块设备。参考《指令指南》中的devb-*来获取更多设备信息。/dev/connTTY控制台设备的文字模式。参考《指令指南》中的devc-con。/dev/console用于诊断日志信息的设备。在一个完整的x86系统中这是个由系统记录器管理的只写设备slogger2。嵌入式系统的构造文件可以在其他设备中配置一个该路径的链接例如一个串口。参考《指令指南》中的slogger2。/dev/hdn硬盘块设备。数据代表了整个驱动跨越所有分区。参考《指令指南》中的devb-*。/dev/hdntn硬盘块设备。这些设备中的数据是hdn对应数据的子集。参考《指令指南》中的devb-*。/dev/mem一个代表了所有物理内存的设备。/dev/mq和/dev/mqueue消息队列条目所在的路径空间。更多信息请参考《指令指南》中的mq和mqueue。/dev/null一个你可以将数据导入其中的‘位桶’bit bucket。这些数据被丢弃了。/dev/pci当前机器上适配PCI服务器的设备该设备允许程序和PCI服务器通讯。参考《指令指南》中的pci-*/dev/pipe适配管道管理器。这个文件的存在告诉其他程序例如构建在OS镜像中启动脚本管道管理器已成功运行。/dev/pty[p-zP-T][0-9a-f]伪终端设备对中的控制端。伪ttys用字母p-z或P-T加十六进制数字命名使其最多又256个设备。请参考《指令指南》中的devc-pty。/dev/random从这个设备读取随机数据。请参考《指令指南》中的random。/dev/sem信号量所在的路径空间。/dev/sern串口。相关配置请查看stty更多设备信息请参考《指令指南》中的devc-ser*/dev/shmem/包含了系统中代表共享内存区域的文件有时也被通用内存映射文件使用。更多信息请参考文件系统操作中RAM文件系统的相关描述。/dev/socket/这个目录是TCP/IP栈所有并管理的它包括了io-ptk*。这个目录包含了应用和栈交互的路径名。更多信息请参考TCP/IP网络章节。/dev/text这个文件被procnto管理。写入这个设备的文字是通过调式输出路径编码在你系统的开机代码中的输出因此每个板子是不同的。在标准的电脑上默认事故写入电脑的控制台。更多信息请参考《指令指南》中的startup-*/dev/tty由进程管理器procnto拥有的虚拟设备。任何进程打开此文件时它都会解析为该进程所在会话对应的控制终端设备。这对于程序来讲是非常有用的它们或许已经关闭了它们的标准输入、标准输出、标准报错并希望把这些写入终端设备。/dev/tty[p-zP-T][0-9a-f]/dev/pty[p-zP-T][0-9a-f]对应的从端文件。典型地程序一般被这些文件中的一个控制其准输入、标准输出、标准报错。/dev/zero提供一个无限长的字节流其中每个字节的值均为零。/etc/etc目录包含了主机专属的系统文件和程序用于管理权限、配置包括/etc/config/包含了系统配置文件的目录例如ttys文件它被tinit用于配置终端设备。/etc/default/包含默认配置文件的目录主要用于TCP/IP设置/etc/dhcpd.conf动态主机配置协议。请参考《指令指南》中的/etc/dhcpd.conf/etc/ftpd.conf文件传输协议ftpd的配置选项一旦你连接或者授权时就会被应用。请参考《指令指南》中的…/…/com.qnx.doc.neutrino.utilities/topic/f/ftpd.conf.html/etc/ftpusers定义了哪些用户可以通过文件传输协议访问机器。请参考《指令指南》中的/etc/ftpusers/etc/group用户账户分组定义。参考《管理用户账户》章节/etc/hosts网络主机名查找数据库参见下述/etc/nsswitch.conf 和 /etc/resolv.conf。请参考《指令指南》中的/etc/hosts/etc/inetd.conf互联网超级服务器配置文件定义了inetd动态开启和关闭时所需的互联网服务。该文件中默认版本的描述被注释掉了没有被注释掉的是你需要。请参考《指令指南》中的/etc/inetd.conf/etc/motd包含了一条用户登录时会显示的ASCII信息是否显示取决于/etc/profile中配置是否会显示它。只有当/etc/motd 文件比你最后一次登录系统时间取决于 $HOME /.lastlogin的修改时间更晚时 /etc/profile默认会显示此文件。更多信息请参考配置你的系统章节中关于/etc/profile的描述/etc/networks网络名数据库。更多信息参考《指令指南》中的/etc/networks/etc/nsswitch.conf命名服务控制配置文件。更多信息《指令指南》中的/etc/nsswitch.conf/etc/opasswd/etc/passwd 最后一次通过passwd指令修改/etc/passwd前的备份。请参考管理用户账户章节。/etc/oshadow/etc/shadow 最后一次通过passwd指令修改/etc/passwd前的备份。请参考管理用户账户章节。/etc/passwd该文件定义了登录账户更多信息请参考登录、登出和关机章节和管理用户账户章节。也可以参考《指令指南》中的passwd , login/etc/profile启动用户配置脚本当你登录时命令行解释器会执行它。它会在$HOME /.profile前被执行。参看配置你的环境章节。/etc/profile.d/默认/etc/profile脚本会在此目录下寻找任一用户登录的脚本。/etc/profile脚本会运行此目录下每个和*.$(SHELL##/}匹配的脚本。例如如果命令行解释器中环境变量的值为/bin/sh那么该脚本会运行所有匹配.sh的脚本。/etc/resolv.conf解析器配置文件参见上述/etc/hosts。请参考《指令指南》中的/etc/resolv.conf/etc/skel/存放.profile默认版本的目录。当你在系统中增加新用户时这个文件会被复制到用户的home目录。更多信息请参考/etc/default/passwd的描述以及配置你的系统章节的.profile/home常规用户的home目录存放在这里。你的目录名和你的用户名是一致的。你可以在你的home目录下创建你需要的任何目录结构lib这个目录包含了基础的共享库和运行所需的程序(文件名 .so),以及开发中所需的静态库。请参考/usr/lib 和 /usr/local/lib./lib目录包括/lib/dll/包含了实现OS驱动和服务的补充共享库例如驱动、文件系统管理器等。更多关于具体类型的驱动和服务如何使用共享库请查看《系统架构指南》中的文件系统、原生网络Qnet和TCP/IP网络。关于/lib/dll中的特定共享库的详细信息请参考《指令指南》中它们各自的条目。/proc属于进程管理器procnto这个虚拟目录可以向你提供关于进程和路径名空间配置的信息。每个进程都在/proc目录下有一个子目录以进程 ID命名。每一个子目录都包含了用以访问进程地址空间的条目如果有适当的权限来控制它们的线程等。许多指令会用到这些条目来获取进程的信息。更多信息请参考《QNX Neutrino程序员指南》中的“通过/proc 文件系统控制进程”章节以及《QNX Neutrino Cookbook》中/proc文件系统附录。/proc目录下也包含以下内容:/proc/boot/包含了启动引导镜像的文件系统镜像。更多信息请参考《构建嵌入式系统》中的操作系统镜像章节/proc/dumper一个接收进程异常结束提醒的特殊条目。dumper指令创建了此条目。/proc/mount/路径名空间的挂载点。如果里列出/proc下的内容/proc/mount并不会在其中但你可以列出/proc/mount中的内容更多信息请参考《QNX Neutrino Cookbook》中/proc文件系统附录中的/proc/mount目录/proc/qnetstat如果你在使用透明分布式处理TDPlsm-qnet.so模块会在/proc中放一个qnetstats条目。如果你打开这个名字并从中读取Qnet资源管理器的代码会对当前Qnxt的统计进行反馈。/proc/self你自身的地址空间为正在进行查询的进程/root/root目录是root用户的home目录/sbin包含系统基础的二进制文件包括驱动devb* , devc* , devf* , devu*初始化程序配置命令ifconfig和修复指令chkqnx6fs , chkdosfs管理器io-pky*,mqueue,pipe/tmp这个目录包含临时文件。一般假设程序会在使用完后删除它们的临时文件但有时由于不好的代码质量和异常中断它们并不这样做。你可以在系统空闲时定期清理无用的文件。/usr/usr目录是一个次级文件层次结构包含可共享的只读数据。它可能会包含以下内容/usr/bin/一个包含了用户最常用指令的目录。例如diff,errno和wc/usr/lib/对象文件库和你不能直接执行或使用脚本执行的中间二进制文件你会在写程序时链接这些库。/usr/libexec/可能包含了守护进程和系统指令总的来说它们只会被其他程序运行/usr/local/最开始是空的系统管理员可以在此安装软件到本地。/usr/sbin/非基础系统二进制文件例如cron、dumper和nocinfo/usr/share/和架构无关的数据例如图标、壁纸和各种gawk程序/var/var路径包含各种数据文件包括缓存文件、锁文件、日志文件等。/var/pps持久化发布/订阅管理器 pps 在关闭时存储“持久化”其状态的目录。用户所有权和权限每个文件和目录都鼠疫一个特定的用户ID和组ID并有一系列相关的权限也叫模式。你可以使用这些指令来控制所有权和权限目的 指令指定文件或目录的权限 chmod改变文件或目录的所有者或组别 chown改变文件或目录的组别 chgrp更多细节请参考《指令指南》*只有当你是文件或目录的所有者或者你以root身份登录时你才可以改变文件或目录的权限如果你既要修改权限又要修改所属权请先修改权限。一旦你把所属权分配给了其他用户你就无法修改全线路。权限类别的划分u用户权限指所有者g组的权限o其他用户的权限指组以外的所有人每个权限包括r读的权限。对于目录来说这是允许列出目录下内容的权限。w写的权限x执行的权限。对于目录来说这是允许在目录下查找的权限。s或SSetuid 或 setgid (见下述描述)。t或T粘滞位见下描述如果你对目录有读的权限但没有搜索的权限你可以看到目录下的文件但是无法读取或修改这些文件的内容。如果你对某个目录假设它是dir有搜索的权限但是没有读的权限的但是对他的子目录假设是dir/subdir有读的权限那么你无法再dir路径下列出所有内容并看到subdir但是如果你出于某种原因知道dir/subdir的存在,你可以直接指定并列出dir/subdir中的内容。如果你列出你home目录下的内容使用ls -al你或许会得到以下输出total94286drwxr-xr-x18barney techies6144Sep2606:37 ./ drwxrwxr-x3root root2048Jul1507:09../ -rw-rw-r--1barney techies320Nov112013.kshrc -rw-rw-r--1barney techies0Aug 08 09:17 .lastlogin -rw-r--r--1barney techies254Nov112013.profile -rw-rw-r--1barney techies3585Jul311993123.html -rw-rw-r--1barney techies185Aug 082014Some_file drwx------2barney techies4096Jul 0411:17 bin/ -rw-------1barney techies34Jul 052002cmd.txt drwxr-xr-x2barney techies2048Feb262014interesting_stuff/ drwxrwxr-x3barney techies2048Oct172002more_stuff/ drwxrwxr-x2barney techies4096Jul 04 09:06 workspace/第一类是权限的集合。以d开头的表示这一项是目录。查看本章前面提及的“文件类型”*如果某项权限后有一个加号该文件或目录拥有一个访问控制列表用于进一步明确权限。更多信息请查看下述“访问控制列表ACLs”你也可以查看表示权限的八进制数查看《指令指南》中的chmodSetuid 和 setgid一些程序例如passwd需要特殊用户运行才能正常工作$which-lpasswd-rwsrwxr-x1root root21544Mar3023:34 /usr/bin/passwd请注意所属权中的第三个字母是s。这代表了setuid“设置用户ID”指令。当你运行passwd时程序会以文件的所有者的身份运行这里是root。S 表示文件的设置用户 IDsetuid位已设置但执行位未设置。你也会找到一些setgid“设置用户组ID”指令它们会使用文件所属的组id运行但不是以所属的用户id运行。如果setgid被设置到了一个目录那么这个目录下创建的文件会有这个目录的组id而不是文件创建者的ID。这种方案通常用于假脱机区spool areas例如/usr/spool/mail,它是setgid 并且被mail组所有因此以mail组身份运行程序可以更新这里的东西但是文件仍属于它们自己的所有者。除非你以root身份登录当你修改一个setuid 命令的归属权时setuid 位会被清空。类似的当你修改一个setuid 命令的归属权时setgid 位会被清空。当你在Windows主机上运行时mkefs 、 mketfs和 mkifs无法从文件中获得执行x、setuid或setgid权限使用perms属性来明确指定指定这些权限。你也可以使用uid和gid属性来正确的指定所属权。更多关于指令是否需要setuid 或 setgid权限请查看《指令指南》中相关条目。注意Setuid 和 setgid指令会造成安全问题。如果你创建了它们需确认只有只有它们的所有者可以写入它们其他可以用户不会黑掉他们特别是那些被root拥有的文件。粘滞位粘滞位sticky bit是一种访问权限它会影响对可执行文件和目录的处理方式如果一个可执行文件设置了这个权限内核希望程序结束后这个内存中的可执行文件还能保留“一段时间”具体时间长度取决于系统中会发生什么。当你经常运行一个程序时这会提高性能。如果这是一个目录粘滞位会影响谁可以删除这个文件。要删除文件你总需要对这个目录有写的权限但是如果这个路径被设置了粘滞位你也需要是这个目录的所有者或者对文件有写的权限。如果权限中的第三个字母是t例如r-t,那么粘滞位和可执行权限都被设置的了。T则代表只设置了粘滞位。默认文件权限使用 umask 命令来指定用于设置新文件权限的掩码。默认掩码是002因此所有的新文件会赋予用户文件的所有者和其他用户组读和写的权利以及所有其他用户读的权利。如果你想移除其他用户读和写的权限在.profile目录中增加如下指令umask 006如果你是系统的管理员并且你希望对所有人应用这项更改修改/etc/profile中的umask设置。更多信息请参考配置你的系统章节。访问控制列表ACLs一些文件系统例如防断电文件系统( fs-qnx6.so )使用访问控制列表来扩展文件权限。传统的用户权限是使用chmod来设置文件全限定如果你想要某些用户对一个文件有特别的权限你只有很有限的一些选择把那个人添加到所属组创建一个包含那个人和文件所有者的补充组别降低“其他”用户的权限跟踪每个用户组的权限可能会变得复杂允许“其他”用户更多的权限会让你的系统不那么安全。ACLs扩展了文件的权限让你可以更好的管理谁可以访问什么。在ACLs中权限被分为以下类别所有者类组类别由指定用户、属组和指定组组成。其他或全局类访问控制列表包含了一系列条目列举在如下表格中通过代码中用于标识标签类型的常量来给出条目类型标签类型格式所有者ACL_USER_OBJuser::permissions指定用户用用户名或数字ID指定ACL_USERuser:user_identifier:permissions所属组ACL_GROUP_OBJgroup::permissions指定组用组名或数字ID指定ACL_GROUPgroup:group_identifier:permissions组别权限上限ACL_MASKmask::permissions其他ACL_OTHERother::permissions权限遵从rwx格式用横杆-替代没有授予的权限。这是一个ACL文件的例子user::rw- user:violetta:r-- group::rw- mask::rw- other::---所有者和所属组有读和写的权限。其他用户没有任何权限。violetta被授予了读的权限她比“其他”有更多特权但是不想所有者和所属组那么多特权。如果“violetta”没有被授予特俗权限那么ACL和rw-rw----权限是一样的。如果一个ACL可以简单到和文件权限一样它可以被称作最小ACL。如果不能它被称作扩展ACL。一个扩展ACL一定有一个掩码条目也可以包含针对指定用户和制定组别任意多的掩码条目。如果一个文件有一个宽展ACL,那ls -l中输出的权限后会有一个加号掩码条目是一个所属组、所有指定用户、所有指定组别的权限几何。例如让我们来看一个文件它的所属组没有写的权限# ls -l file.txt-rw-r--r--1mabel techies50Sep2721:22 file.txt如果我们用getfacl指令来获取它的ACL,我们可以看到# getfacl -q file.txtuser::rw- group::r-- other::r---q 选项会抑制 getfacl 默认显示的某些注释仅列出文件名、所有者和属组。下一步让我们假设“mable”用setfacl给“frank”增加了一条授予他读和写权限的条目要修改ACL你必须是这个文件或目录的所有者或者你有适当的特权# setfacl -m u:frank:rw- file.txt# getfacl -q file.txtuser::rw- user:frank:rw- group::r-- mask::rw- other::r--# ls -l file.txt-rw-rw-r--1mabel techies50Sep2721:22 file.txt除了给“frank”的条目ACL现在包括了一个列出了读和写权限的条目。ls的输出也表明组有读和写的权限。修改文件权限例如使用chmod会影响ACLs反之亦然。文件的用户权限和ACL中所有者的权限条目永远匹配“其他”权限和ACL中“其他”权限的条目永远匹配如果ALC中没有掩码条目那么组权限和ACL中的组权限条目匹配如果ACL中有掩码条目那么组权限不一定和ACL中的组权限条目匹配让我们继续来看这个文件的例子现在“mable”使用库chmod移除了组的写入权限# chmod g-w file.txt# getfacl -q file.txtuser::rw- user:frank:rw-# effective: r--group::r-- mask::r-- other::r--# ls -l file.txt-rw-r--r--1mabetechies50Sep2721:22 file.txt“frank”条目仍列出了读和写的权限但是一条备注警告我们只有读的权限是有效的因为我们在掩码中明确移除了写的权限。以下伪代码展示了检查文件或目录访问权的算法if(the processs effective user ID matches the object owners user ID){The matched entry is the owner ACL entry}elseif(the processs effective user ID matches the user ID specified in any named user ACL entry){The matched entry is the matching named user entry}elseif(the processs effective group ID or any of its supplementary group IDs matches the group ID of the object or matches the group ID specified in any named group entry){if(the requested access modes are granted by at least one entry matched by the processs effective group ID or any of its supplementary group IDs){The matched entry is one of the grantingentries(it doesnt matter which)}else{Access is denied}}elseif(the requested access modes are granted by the “other” ACL entry){The matched entry is the “other” entry}if(the requested access modes are granted by the matched entry){if(the matched entry is the owning user or “other” entry){Access is granted}elseif(the requested access modes are also granted by the mask entry,or no mask entry exists in the ACL){Access is granted}else{Access is denied}}else{Access is denied}更多信息请参考《指令指南》中的 getfacl 或 setfacl。你的程序也可以使用一些函数来操作ACLs,更多相关信息请参考《QNX Neutrino程序员指南》以及《QNX Neutrino C库指南》中的acl_*()条目*POSIX 草案还描述了默认 ACL这些默认 ACL 规定了在目录内创建的新对象的初始 ACL。目前尚未实现默认 ACL。cp指令不会拷贝原文件的ACL但如果目标文件已经存在ACL那么这个ACL会被保留。文件扩展名下表列出了一些QNX Neutrino系统场景文件扩展名展名描述相关程序/工具.1Troff 格式文本例如来自 Unix “man”手册页面的内容。man 和 troff第三方软件.a库归档文件ar.awkAwk 脚本gawk.b基准计算器库或程序bc.batMS-DOS 批处理文件用于 DOS 系统在 QNX Neutrino 下无法运行。有关为 QNX Neutrino 编写 shell 脚本的信息请参阅“编写 Shell 脚本”和 ksh。.build操作系统镜像构建文件mkifs.cC 程序源代码qcc, make.C, .cc, .cppC 程序源代码q, make.cfg配置文件各种格式各种程序格式不同.conf配置文件各种格式各种程序格式不同.css层叠样式表在 IDE 中用于文档.defC 定义文件q, make.dllMS-Windows 动态链接库不直接在 QNX Neutrino 中使用某些在 MS-Windows 下运行的程序例如部分 QNX Neutrino 工具需要。等效的 QNX Neutrino 格式请参阅 .so共享对象。.gz压缩文件gzip另请参阅“备份与恢复数据”.hC 头文件qcc, make.htm用于网页浏览的超文本标记语言HTML文件网页浏览器.ifs, .imgQNX Neutrino 镜像文件系统通常是可启动镜像mkifs另请参阅《构建嵌入式系统》中的“操作系统镜像”.jarJava 归档文件由多个 Java 文件类文件等压缩成单个文件Java 应用程序例如 IDE.kev内核事件由插桩内核收集用于分析整个 QNX Neutrino 系统procnto*-instr, tracelogger, traceprinter, IDE另请参阅《系统分析工具包用户指南》.mkMakefile 源文件通常在 QNX Neutrino 递归 make 中使用make.o编译 C、C 或汇编源文件后产生的二进制输出文件qcc, make.S, .s汇编源代码文件GNU 汇编器 as.so, .so.n共享对象qcc, make.tar磁带归档tar另请参阅“备份与恢复数据”.tar.gz, .tgz压缩的磁带归档gzip, tar另请参阅“备份与恢复数据”.txtASCII 文本文件许多基于文本的编辑器、应用程序和用户.use用于未将用法信息嵌入程序源代码的程序的用法消息源QNX Neutrino 递归 makemake.wav音频波形文件.xml可扩展标记语言文件多种用途包括 IDE 文档.zip压缩归档文件gzip如果你不确定你文件的类型使用file指令file文件名故障排查以下是你可能遇到的一些问题我试图写入一个文件但收到了“权限被拒绝”的提示。你没有写入该文件的权限如果你是文件的的所有者或root你可以修改权限。查看上述“文件所属权和权限”。我有目录写入权限当我试图列出目录内容却收到了“权限被拒绝”的提示。你需要读取权限才能列出目录内容以及执行权限来对目录下的内容操作。查看上述“文件所属权和权限”。文件名中有空格时会出问题命令解释器或shell会使用空格字符来将命令拆分成命令词。如果你的文件名中包含空格你需要用“引号”把空格引用起来让shell知道这就是一个真实的空格。更多信息包括其他你需要了解的特殊字符请参考使用命令行章节的引用特殊字符。