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

Shell 文件操作

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

由 娃娃脸呦 创建,Loen 最后一次修改 2016-02-24 前言这周来探讨文件操作。在日常学习和工作中,总是在不断地和各种文件打交道,这些文件包括普通文本文件,可以执行的程序,带有控制字符的文档、存放各种文件的目录、网络套接字文件、设备文件等。这些文件又具有诸如属主、大小、创建和修改日期等各种属性。文件对应文件系统的一些数据块,对应磁盘等存储设备的一片连续空间,对应于显示设备却是一些具有不同形状的字符集。在这一节,为了把关注点定位在文件本身,不会深入探讨文件系统以及存储设备是如何组织文件的(在后续章节再深入探讨),而是探讨对它最熟悉的一面,即把文件当成是一系列的字符(一个 byte)集合看待。因此之前介绍的《 Shell 编程范例之字符串操作》在这里将会得到广泛的应用,关于普通文件的读写操作已经非常熟练,那就是“重定向”,这里会把这部分独立出来介绍。关于文件在 Linux 下的“数字化”(文件描述符)高度抽象,“一切皆为文件”的哲学在 Shell 编程里也得到了深刻的体现。下面先来介绍文件的各种属性,然后介绍普通文件的一般操作。文件的各种属性首先通过文件的结构体来看看文件到底有哪些属性:struct stat { dev_t st_dev; /* 设备 */ ino_t st_ino; /* 节点 */ mode_t st_mode; /* 模式 */ nlink_t st_nlink; /* 硬连接 */ uid_t st_uid; /* 用户ID */ gid_t st_gid; /* 组ID */ dev_t st_rdev; /* 设备类型 */ off_t st_off; /* 文件字节数 */ unsigned long st_blksize; /* 块大小 */ unsigned long st_blocks; /* 块数 */ time_t st_atime; /* 最后一次访问时间 */ time_t st_mtime; /* 最后一次修改时间 */ time_t st_ctime; /* 最后一次改变时间(指属性) */};下面逐次来了解这些属性,如果需要查看某个文件属性,用 stat 命令就可,它会按照上面的结构体把信息列出来。另外,ls 命令在跟上一定参数后也可以显示文件的相关属性,比如 -l 参数。文件类型文件类型对应于上面的 st_mode, 文件类型有很多,比如常规文件、符号链接(硬链接、软链接)、管道文件、设备文件(符号设备、块设备)、socket文件等,不同的文件类型对应不同的功能和作用。范例:在命令行简单地区分各类文件$ ls -ltotal 12drwxr-xr-x 2 root root 4096 2007-12-07 20:08 directory_fileprw-r--r-- 1 root root 0 2007-12-07 20:18 fifo_pipebrw-r--r-- 1 root root 3, 1 2007-12-07 21:44 hda1_block_dev_filecrw-r--r-- 1 root root 1, 3 2007-12-07 21:43 null_char_dev_file-rw-r--r-- 2 root root 506 2007-12-07 21:55 regular_file-rw-r--r-- 2 root root 506 2007-12-07 21:55 regular_file_hard_linklrwxrwxrwx 1 root root 12 2007-12-07 20:15 regular_file_soft_link -> regular_file$ stat directory_file/ File: `directory_file/' Size: 4096 Blocks: 8 IO Block: 4096 directoryDevice: 301h/769d Inode: 521521 Links: 2Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)Access: 2007-12-07 20:08:18.000000000 +0800Modify: 2007-12-07 20:08:18.000000000 +0800Change: 2007-12-07 20:08:18.000000000 +0800$ stat null_char_dev_file File: `null_char_dev_file' Size: 0 Blocks: 0 IO Block: 4096 character special fileDevice: 301h/769d Inode: 521240 Links: 1 Device type: 1,3Access: (0644/crw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)Access: 2007-12-07 21:43:38.000000000 +0800Modify: 2007-12-07 21:43:38.000000000 +0800Change: 2007-12-07 21:43:38.000000000 +0800说明:通过 ls 命令结果每行的第一个字符可以看到,它们之间都不相同,这正好反应了不同文件的类型。 d 表示目录,- 表示普通文件(或者硬链接),l 表示符号链接,p 表示管道文件,b 和 c 分别表示块设备和字符设备(另外 s 表示 socket 文件)。在 stat 命令的结果中,可以在第二行的最后找到说明,从上面的操作可以看出,directory_file 是目录,stat 命令的结果中用 directory 表示,而 null_char_dev_file 它则用 character special file 说明。范例:简单比较它们的异同通常只会用到目录、普通文件、以及符号链接,很少碰到其他类型的文件,不过这些文件还是各有用处的,如果要做嵌入式开发或者进程通信等,可能会涉及到设备文件、有名管道(FIFO)。下面通过简单的操作来反应它们之间的区别(具体原理会在下一节《Shell 编程范例之文件系统》介绍,如果感兴趣,也可以提前到网上找找设备文件的作用、块设备和字符设备的区别、以及驱动程序中如何编写相关设备驱动等)。对于普通文件:就是一系列字符的集合,所以可以读、写等$ echo "hello, world" > regular_file$ cat regular_filehello, world在目录中可以创建新文件,所以目录还有叫法:文件夹,到后面会分析目录文件的结构体,它实际上存放了它下面的各个文件的文件名。$ cd directory_file$ touch file1 file2 file3对于有名管道,操作起来比较有意思:如果要读它,除非有内容,否则阻塞;如果要写它,除非有人来读,否则阻塞。它常用于进程通信中。可以打开两个终端 terminal1 和 terminal2,试试看:terminal1$ cat fifo_pipe #刚开始阻塞在这里,直到下面的写动作发生,才打印test字符串terminal2$ echo "test" > fifo_pipe关于块设备,字符设备,设备文件对应于 /dev/hda1 和 /dev/null,如果用过 U 盘,或者是写过简单的脚本的话,这样的用法应该用过::-)$ mount hda1_block_dev_file /mnt #挂载硬盘的第一个分区到/mnt下(关于挂载的原理,在下一节讨论)$ echo "fewfewfef" > /dev/null #/dev/null像个黑洞,什么东西丢进去都消失殆尽最后两个文件分别是 regular_file 文件的硬链接和软链接,去读写它们,他们的内容是相同的,不过去删除它们,他们却互不相干,硬链接和软链接又有何不同呢?前者可以说就是原文件,后者呢只是有那么一个 inode,但没有实际

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


Shell 文件操作