Linux/Unix的精巧约定两例及其简析:目录权限和文本行数

学玩*nux时候,碰到的一些问题,弄明白了后也就过去了。今天看到旁边的同学对目录权限有些模糊,给解释了一下。想想不如把这些问题都记下来。

设计其实包含的是一套约定。能运行、解决问题的约定都是可用的约定。但解决的多种约定方式或说是设计中,作一些比较可以感觉到哪个会更统一更简单。下文提到的两例Linux/Unix约定说明后,我也简单分析一下约定,找出看似复杂或是不直觉约定中内部包含的简洁统一。

清楚的同学,就当是个活动脑子的问题,过一遍小乐一下  如有谬误敬请指正。

目录权限的约定

目录的执行权限

普通文件(非目录)有执行权限、执行操作,很容易理解,目录执行权限是个啥?

我期望以尽量简明统一方式来描述:

目录的执行权限 是 下面操作的前提:

  1. 该目录下的文件(包含子目录)的读、写、执行操作(即目录下文件的全部操作)
  2. 该目录本身的写操作

注: 要对目录进行写操作,要同时有该目录的写权限 和 该目录的执行权限

详见《Unix环境高级编程》第四章第5节“文件访问权限”;中文版第二版在第76页。

多谢My Friend and Mentor kiminotes同学半夜还和我一起验证和确认这个问题,并给我找出了上面资料。

关于上面提到的目录的读、写操作的说明在下一节给出。

示例说明和分析

上面条款1实际上包含有递归说明

  1. 目录的执行权限前提要有父目录的执行权限;
  2. 父目录的执行权限的前提是要有父目录的父目录的执行权限;
  3. ……

举个例子来讲解一下,比如要读文件/home/foo/readme.txt

  1. 要读readme.txt,前提要可以执行父目录foo
  2. 要执行foo目录,前提要可以执行父目录home
  3. 要执行home目录,前提要可以执行父目录/(即root目录)root目录没有父目录了(或者说,root目录的父目录是自己),递归终止。

上面分析的结果是,要读文件/home/foo/readme.txt需要:

  1. readme.txt的读权限
  2. foo目录的执行权限
  3. home目录的执行权限
  4. /目录的执行权限

通过上面分析可以看出,目录的执行权限是对其下子文件进行操作的前提,所以只要对自己的Home目录的权限改成700,就可以拒绝他人查看自己Home下的文件的内容、在目录下新建或是删除文件。

# 如果只给他Home目录的读权限,还是可以list出Home下有哪些文件,见下一节的说明

$ chmod 700 .
$ ls -ld .
drwx----- 9 foo foo 4.0K 2012-11-20 00:11 ./

注: ls-d表示list文件是目录时,不去list目录下文件,而是list目录本身。

目录读、写操作

普通文件(非目录)的读、写操作很容易理解。目录的读、写操作说明如下:

  • 目录读操作 = 可以list出目录下有哪些文件
  • 写操作 = 可以在该目录下新建删除这个目录下的文件(包含新建和删除子目录)

注:要对目录进行写操作,前提要同时有该目录的写权限 和 该目录的执行权限

所以,为了删除一个现有的文件,必须对包含该文件的目录具有写权限执行权限;对该文件本身不需要有读、写权限。

讨论

目录这些权限的约定,让整个目录(包含下面所有的子文件)的控制变得简单,简单调整这个目录上的执行权限就可以了;信息集中,方便维护。

想想Windows的约定吧,是不是想到那个“应用到所有子目录和文件”的选项,要把所有的子目录都设置一遍。

最早开始期望一句话来描述“目录的执行权限”,即只有条款1,结果发现还有条款2的内容,是“该目录本身的写操作”的前提。

注: 关于文件权限详细说明,对应系统调用,可以参见《Unix环境高级编程》第四章第5节“文件访问权限”。

这样不统一的描述,让我感觉到条款2可能是Unix设计为了解决一些实际问题而补入的条款。我的YY的场景是:

限制对HOME目录的操作(增删子文件,包含的递归子文件),如果没有条款2,关掉别人对HOME目录执行权限还不够,还要通过关掉别人对HOME目录写权限来限制。这样的常见需求两步操作就繁琐了!

文本行数的约定

文本的行数 = 文本中换行符的个数

可以使用下面的命令验证:

$ echo -n blablabla | wc
0 1 9

看到统计行数的结果是0行。

注: echo-n选项表示不输出换行。

为什么这么约定

方便统计文本行数

“文本的行数 = 文本中换行符的个数”的约定,只要找到换行就好。

不需要特殊处理最后一行可能没有换行。

# Windows下不做这个约定,就要有这样的特殊处理。

方便程序输出文本

想想写个程序按行输出结果。

如果输出最后一个结果后不要换行:

int len = 10;
int[] result = ...;
for(int i = 0; i < len; ++i) {
if(i != 0) { // 如果不是第一个
printf("n");
}
printf("%d", i);
}

如果每输出一个结果带一个换行:

int len = 10;
int[] result = ...;
for(int i = 0; i < len; ++i) {
printf("%dn", i);
}

这两种写法,第二种没有if判断,更整齐、更简单。

讨论

从上面2种情况,一种是统计输入文本行数,一种输出多行文本,这个约定都简化实现和说明。简单是美。

你可能发现,这个约定简单是对于程序,对于人来做就麻烦了,要保证最后一行后面有换行符!

实际上Linux/Unix下的文本编辑器会遵循这个约定,编辑时会自动给最后一行没有换行的文本加上一个换行。

这样这个约定就不会给人带来麻烦了,让编辑器来维护这个约定。

可以这样验证:

生成不带结尾换行的文件。

$ echo -n blablabla > test.txt
$ wc test.txt
0 1 9 test.txt

用vi打开编辑,第一行行头加一个字符后保存退出,wc统计一下,已经有一行文本了。

$ wc test.txt
1 1 11 test.txt

注: Eclipse里有时会提醒你一个Warning说文件不是以换行符结束(No newline at end of file),现在知道为什么了吧 

后记

*nix的设计和约定博大精深,以后发现些新有意思的条目会加进来。

时间: 2024-08-21 16:58:44

Linux/Unix的精巧约定两例及其简析:目录权限和文本行数的相关文章

《Linux/UNIX OpenLDAP实战指南》——2.6 OpenLDAP目录树规划

2.6 OpenLDAP目录树规划 2.6.1 规划OpenLDAP目录树组织架构 要规划OpenLDAP目录树组织架构,可按以下步骤操作. 1)将规划的DN添加到OpenLDAP目录树中.也可以将如下内容添加至ldif文件中,然后通过ldapadd进行导入即可. [root@mldap01 ~]# cat << EOF | ldapadd -x -D cn=Manager,dc=gdy,dc=com -W dn: dc=gdy, dc=com dc: gdy objectClass: top

《Linux/UNIX OpenLDAP实战指南》——1.4 OpenLDAP目录条目概述

1.4 OpenLDAP目录条目概述 1.4.1 objectClass分类 objectClass类通常分三类:结构型.辅助型.抽象型. 结构型(structural):如person和organizationUnit. 辅助型(auxiliary):如extensibleObject. 抽象型(abstract):如top,抽象型的objectClass不能直接使用.1.4.2 OpenLDAP常见的objectClass OpenLDAP常见的objectClass类如下所示. alias

Linux/Unix下安装Perl模块的两种方法分享_perl

方法一.手工安装的步骤 从CPAN下载了DBI模块1.13版的压缩文件DBI-1.13.tar.gz,假设放在/usr/local/src/下. cd /usr/local/src 解压缩这个文件: tar xvzf DBI-1.13.tar.gz 这时会新建一个DBI-1.13的目录. cd DBI-1.13 生成makefile: perl Makefile.PL 建立模块 make 测试模块 make test 如果测试结果报告"all test ok",您就可以放心地安装编译好

Linux/Unix下ODBC的安装、配置与编程

odbc|unix|编程 Linux/Unix下ODBC的安装.配置与编程 齐亮 (cavendish@eyou.com) 2002 年 7 月 本文主要内容是介绍ODBC的简单原理,以及如何在Linux/Unix下进行ODBC的安装.配置与编程. 一. ODBC原理 ODBC 是Open Database Connect 即开放数据库互连的简称,它是由Microsoft 公司于1991 年提出的一个用于访问数据库的统一界面标准,是应用程序和数据库系统之间的中间件.它通过使用相应应用平台上和所需

10个 Linux/Unix下 Bash 和 KSH shell 的作业控制实例

Linux 和 Unix 属于多任务的操作系统,也就是说一个系统在同一时间段内能运行多重任务(进程).在这个新的博客系列,我将会列出相关的 Linux 和 Unix 作业(job)控制的命令,你可以通过这些命令在 Bash 或 Korn 还有 POSIX shell 下实现执行多重任务. 什么是作业控制? 作业控制不只是能够停止/挂起(stop/suspend)正在执行的进程(命令),也可以继续/唤醒(continue/resume)执行你需要的每一个进程.这完全可以用你的操作系统和 bash/

linux/unix 段错误捕获【续】

本文为"在C/C++中捕获段错误,打印出错的具体位置"的续篇,进一步解决涉及动态链接库的情况.   背景知识: ·linux/unix下动态链接库的基本原理 ·/proc/pid/maps文件的基本格式 ·动态链接库:在进程执行过程中动态加载,进程间可以共享代码,可用在发布升级包等场合   概述:     用户自己编写的代码均编译进了可执行文件里的时候,"在C/C++中捕获段错误,打印出错的具体位置"里给出了在发生段错误(或其他错误,读者可以修改附件里面的头文件,增

Linux/Unix shell 调用 PL/SQL

    Linux/Unix 下除了调用SQL之外,调用PL/SQL也是DBA经常碰到的情形,下面主要通过一些示例给出如何在shell下面来调用pl/sql.     其它相关的参考:        Linux/Unix shell 脚本中调用SQL,RMAN脚本         Linux/Unix shell sql 之间传递变量 1.将pl/sql代码逐行输入到临时文件 robin@SZDB:~/dba_scripts/custom/bin> more shell_call_plsql.s

Linux / Unix:chroot 命令实例讲解

一个刚接触 Linux 和 Unix 的新手.我该如何改变一个命令的根目录?我要怎样改变一个进程的根目录呢,比如用 chroot 命令将web服务与文件系统隔离?我要如何使用 chroot 恢复密码或修复基于 Linux/Unix的受损坏的环境? 在 Linux和类 Unix 系统下每一个进程/命令的当前工作目录称之为进程/命令的根目录(译注:译者以为此处有误,实际上没有进行过chroot的进程,其根目录是系统的根目录,而不是其工作目录).你可以使用 chroot 命令改变一个命令的根目录,这最

Linux/Unix环境下的Make和Makefile详解_unix linux

Linux/Unix环境下的Make和Makefile详解  无论是在Linux还是在Unix环境中,make都是一个非常重要的编译命令.不管是自己进行项目开发还是安装应用软件,我们都经常要用到make或make install.利用make工具,我们可以将大型的开发项目分解成为多个更易于管理的模块,对于一个包括几百个源文件的应用程序,使用make和makefile工具就可以简洁明快地理顺各个源文件之间纷繁复杂的相互关系.而且如此多的源文件,如果每次都要键入gcc命令进行编译的话,那对程序员来说