Chinaunix首页 | 论坛 | 博客

分类: Python/Ruby

2014-02-18 23:30:24

    #! /usr/bin/env python3        #指明python解释其的位置
    # Variant of "which".
    # On stderr, near and total misses are reported.
    # '-l' argument adds ls -l of each file found.

    import sys
    if sys.path[0] in (".", ""): del sys.path[0]        #1、了解列表sys.apth的作用;  2、了解"."与""的作用 
    import sys, os        #make sure module os is imported from python
    from stat import *

    #定义出错函数
    def msg(str):
        sys.stderr.write(str + '\n')        #写到了标准错误中

    def main():
        pathlist = os.environ['PATH'].split(os.pathsep)        #注意sys.path与os.environ['PATH']的区别
        sts = 0                                                                 
        longlist = ''        #如果有 -l 则保存该字符串

        if sys.argv[1:] and sys.argv[1][:2] == '-l':        #argv[0]永远保存的是python脚本的名称。
            longlist = sys.argv[1]
            del sys.argv[1]                                                    

        for prog in sys.argv[1:]:
            ident = ()        #1、python原则,变量必须先定义后使用;2、注意,空的元组的作用
            for dir in pathlist:
                filename = os.path.join(dir, prog)        #os.path.join is used to construct a path, not like join in class str
                try:
                    st = os.stat(filename)        #get the attribute of file
                except os.error:
                    continue
                if not S_ISREG(st[ST_MODE]):        #it must be a disk file. 
                    msg(filename + ': not a disk file')
                else:
                    mode = S_IMODE(st[ST_MODE])        #获取文件的权限信息
                    if mode & 0o111:        #确保是可执行文件
                        if not ident:
                            print(filename)        #print the path information
                            ident = st[:3]        #get the id infomation of i-node.
                        else:
                            if st[:3] == ident:        #可能跟软/硬链接有关系,无论是软链接还是硬链接,id信息一致. 注意,判别多个值相等的方法.
                                s = 'same as: '
                            else:
                                s = 'also: '
                            msg(s + filename)
                    else:
                        msg(filename + ': not executable')
                if longlist:
                    sts = os.system('ls ' + longlist + ' ' + filename)        #os.system会打印信息,且成功后会返回0
                    if sts: msg('"ls -l" exit status: ' + repr(sts))
            if not ident:
                msg(prog + ': not found')
                sts = 1

        sys.exit(sts)

    if __name__ == '__main__':                                                    #防止该py作为模块运行.
        main()


总结如下:
1、S_ISREG(st[ST_MODE])的具体操作? 可将st理解为序列,所以ST_MODE就是一个数值下标,S_ISREG()是测试文件是否为普通文件,即ll时显示的'-'. 测试如下:
    >>> from stat import *
    >>> st = os.stat('ipt.sh')
    >>> st
    posix.stat_result(st_mode=33261, st_ino=3940080L, st_dev=2049L, st_nlink=1, st_uid=0, st_gid=0, st_size=170L, st_atime=1389791438, st_mtime=138979    1424, st_ctime=1389791433)
    >>> ST_MODE
    0
    有对S_ISREG(st[ST_MODE])的使用进行测试, 地址为: S_ISREG测试文件是否是linux中的'-',普通文件.

2、which.py对软链接和硬链接的处理方式.
    help(st)      
        st_ino        inode
          st_mode     protection bits
        st_dev        device
    注意:which.py并没有区分硬链接和软链接的不同,凡是这三部分相同就认为式统一个文件.
唯一表示节点的三部分信息. 尤其是i-node,在硬链接中,i-node的值是相同的,在软链接中值是不相同的。但是,测试结果却存在差异。
以下是在Linux下的测试结果.

Linux系统下:
    3940080 -rwxr-xr-x 2    root   root   170  1月 15 21:10 test2.sh
    3937107 lrwxrwxrwx 1    xxxx   xxxx    6   2月 20 21:31 test.sh -> ipt.sh
    3940080 -rwxr-xr-x 2    root   root   170  1月 15 21:10 ipt.sh
其中,test2是ipt.sh的一个硬链接,test.sh是ipt.sh的一个软链接。

Python测试如下:
>>> st = os.stat('test.sh')
>>> st
posix.stat_result(st_mode=33261, st_ino=3940080L, st_dev=2049L, st_nlink=2, st_uid=0, st_gid=0, st_size=170L, st_atime=1392902923, st_mtime=1389791424, st_ctime=1392903066)
>>> st = os.stat('test2.sh')
>>> st
posix.stat_result(st_mode=33261, st_ino=3940080L, st_dev=2049L, st_nlink=2, st_uid=0, st_gid=0, st_size=170L, st_atime=1392902923, st_mtime=1389791424, st_ctime=1392903066)
>>> st = os.stat('ipt.sh')
>>> st
posix.stat_result(st_mode=33261, st_ino=3940080L, st_dev=2049L, st_nlink=2, st_uid=0, st_gid=0, st_size=170L, st_atime=1392902923, st_mtime=1389791424, st_ctime=1392903066)
从以上打印结果可以看出,test.sh的inode值是不正确的。
在Python下,它认为硬链接和软链接是一样的,即它直接读软链接对应的文件的i-node信息.

阅读(8200) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~