第十章实践
实践内容:理解ls、who、echostate、filesize、fileinfo、spwd、testioctl等c语言代码,学习ls.exe中的视频内容。
一、ls
ls命令是linux下最常用的命令之一,ls跟dos下的dir命令是一样的都是用来列出目录下的文件,下面我们就来一起看看ls的用法
英文全名:List即列表的意思,当我们学习某种东西的时候要做到知其所以然,当你知道了这个东西大概是个什么了以后你的思维就会联想到很多的东西学习的就会很快。
- ls -a 列出文件下所有的文件,包括以“.“开头的隐藏文件(linux下文件隐藏文件是以.开头的,如果存在..代表存在着父目录)。
- ls -l 列出文件的详细信息,如创建者,创建时间,文件的读写权限列表等等。
- ls -F 在每一个文件的末尾加上一个字符说明该文件的类型。"@"表示符号链接、"|"表示FIFOS、"/"表示目录、"="表示套接字。
- ls -s 在每个文件的后面打印出文件的大小。 size(大小)
- ls -t 按时间进行文件的排序 Time(时间)
- ls -A 列出除了"."和".."以外的文件。
- ls -R 将目录下所有的子目录的文件都列出来,相当于我们编程中的“递归”实现
- ls -L 列出文件的链接名。Link(链接)
- ls -S 以文件的大小进行排序
以上是一些关于ls命令的一些用法,当然还有好多没有列出来,可以man一下。
ls可以结合管道符”|“来进行一下复杂的操作。比如: ls | less用于实现文件列表的分页,ls
二、who
who命令
功能:显示哪些用户登录
用法: who [OPTION]... [ FILE | ARG1 ARG2 ]
参数:
-a,--all:显示所有信息,与-b -d --login -p -r -t -T -u相同
-b,--boot:显示系统最后一次启动的时间
-d,--dead:显示死进程
-H,--heading:显示每一列头名称
-l,--login:显示登录进程号
--lookup:通过DNS解析主机名
-m:只显示标准输入相关的主机名和用户
-p,--process:显示由init生成子进程
-q,--count:显示登录的用户数
-r,--runlevel:当前的runlevel
-s,--short:显示name,line,time三列(默认)
-t,--time:显示系统时钟最后修改时间
-T, -w, --mesg,--message,--writable:显示用户信息状态(+,-,?三种)
-u,--user:显示登录的用户
--version:版本
--help:帮助
三、file
改变目录:cd
回到家目录 cd或者cd~
查看当前目录:pwd
查看目录下的文件的详细信息:ls -l /tmp(显示的最近一次修改的时间)
创建目录:mkdir /tmp/test
创建文件:touch /tmp/test.txt
touch -r file1 file2(将file2的时间记录改成和file1一样)
删除文件:rm /tmp/test.txt (-f 没有提示信息)
删除文件夹:rm -r /tmp/test.txt (-f 没有提示信息)
复制文件:cp /tmp/res.txt /tmp/des.txt
复制文件夹和文件夹中的内容: cp -r dir/* /tmp/( * :所有文件和文件夹 ?:一个字符)
移动文件 mv /tmp/res.txt /tmp/des.txt
查找命令
find [路径] [参数]
参数说明:
时间:
-atimen :在 n*24小时内被 access 即存取过的文件列出来!
-ctimen :在 n*24小时内被 changed 即改变、新增的文件或目录印出
-mtimen :在 n*24小时内被 modified 即修改过的文件印出
-newer file :比 file 还要新的文件就列出来!
使用名称:
-gidn :寻找 群组 ID 为 n 的文件
-group name :寻找群组名称为 name的文件
-uidn :寻找拥有者 ID 为 n 的文件
-user name :寻找使用者名称为 name 的文件
-name file :寻找档名为 file 的文件名称(可以使用万用字符)
-type type :寻找档案属性为 type 的档案,type 包含了 b, c, d, p, l, s,这些与前一章的属性相同!例如 l 为 Link而 d 为路径之意!
例如
[root@bestlinux ~]# find / -nametesting //查找名为 testing 的文件
[root@bestlinux ~]# find / -name'test*' //查找以test开头的文件
[root@bestlinux ~]# find . -ctime1 //查找当前目录下一天内新增的文件
[root@bestlinux ~]# find /home -usertest //查找 /home下拥有者为 test 的文件
which ls(which也可以查找)
查看文件内容
cat /etc/services
head -n /etc/services(查看文件前n行的内容)
tail -n /etc/services(查看文件后n行内容)
管道
more /etc/services (文件内容会一屏一屏的显示出来,你只需用空格键就可以下翻了)
cat /etc/services | more(cat显示出来的内容重新输出给 more 命令就可以达到想要效果)
重定向
cat /etc/services > a.txt(输出重定向只需要加上> 这位一个符号就可以了)
统计文件内容的行数
wc -l /etc/services
返回文件开头的快捷键 gg
返回文件末尾的快捷键 shift+g(即G)
4.细节实现模块
1.filesize st_size计算文件的字节数大小
2.fileinfo 显示文件信息
(1)用来实现显示文件信息,建立了一个stat数据结构。
(2)要先判断命令是否有操作数
3.spwd 列出当前目录
4.ioctl函数
ioctl 用于向设备发控制和配置命令 ,有些命令需要控制参数,这些数据是不能用read / write 读写的,称为Out-of-band数据。也就是说,read / write 读写的数据是in-band数据,是I/O操作的主体,而ioctl 命令传送的是控制信息,其中的数据是辅助的数据。
testioctl ioctl 命令传送的是控制信息,其中的数据是辅助的数据。
5.echostate setecho
.setecho
设置回显位的状态,命令行参数为y则开启,否则关闭。
1.标准输入的文件描述符为0.
2.使用tcgetattr()函数和termios结构体可获得标准输入的属性。
3.使用tcsetattr()函数和termios结构体可以将更改后的属性设置重新写回标准输入。
.echostate
读取驱动设置并显示回显位的状态。
1.标准输入的文件描述符为0
2.使用tcgetattr()函数和termios结构体可以读取到设备的属性
3.回显位状态放置在termios.c_lflag中
6.cp: 复制文件或目录
cp指令用于复制文件或目录,如同时指定两个以上的文件或目录,且最后的目的地是一个已经存在的目录,则它会把前面指定的所有文件或目录复制到此目录中。若同时指定多个文件或目录,而最后的目的地并非一个已存在的目录,则会出现错误信息,将文件file1复制成文件file2(cp file1 file2)
7.fprintf
格式化输出到一个流/文件中
头文件 #include
函数原型 int fprintf(FILE stream,char format,[argument])
8.open
打开一个文件
头文件 #include<fcntl.h>
函数原型 int fd = open(char *name,int how)
9.write
将内存中的数据写入文件
头文件 #include<unistd.h>
10.create
创建/重写一个文件
头文件 #include<fcntl.h>
函数原型 int fd = creat(char *filename,mode_t mode)
11.read
将数据读到缓冲区
头文件 #include<unistd.h>
函数原型 ssize_t numread = read(int fd,void *buf,size_t qty)
12.close
关闭一个文件
头文件 #include<unistd.h>
函数原型 int result = close(int fd)
5.struct stat
stat,lstat,fstat1 函数都是 获取文件(普通文件,目录,管道,socket,字符,块()的属性。
函数原型#include <sys/stat.h>
int stat(const char *restrict pathname, struct stat *restrict buf);提供文件名字,获取文件对应属性。
int fstat(int filedes, struct stat *buf); // 通过文件描述符 获取文件对应的属性。
int lstat(const char *restrict pathname, struct stat *restrict buf);连接文件描述命,获取文件属性。2 文件对应的属性;
描述: fstat()用来将参数filedes 所指向的文件状态复制到参数buf 所指向的结构中(structstat)。fstat()与stat()作用完全相同,不同之处在于传入的参数为已打开的文件描述符。
返回值:执行成功返回0,失败返回-1,错误代码保存在errno。
下面举一个小例子:
------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
main()
{
struct stat buf;
intfd;
fd = open( "/etc/passwd", O_RDONLY);
fstat (fd,&buf);
printf("/etc/passwd file size = %d\n",(int)(buf.st_size));
}
------------------------------
执行结果:
/etc/passwd file size = 1656
看到这里我会有疑惑:这个struct stat 结构到底是什么样的?
struct stat结构体
定义如下:
struct stat {
dev_t st_dev; // 文件所在设备ID
ino_t st_ino; // 结点(inode)编号
mode_t st_mode; // 保护模式
nlink_t st_nlink; // 硬链接个数
uid_t st_uid; // 所有者用户ID
gid_t st_gid; // 所有者组ID
dev_t st_rdev; // 设备ID(如果是特殊文件)
off_t st_size; // 总体尺寸,以字节为单位
blksize_t st_blksize; // 文件系统 I/O 块大小
blkcnt_t st_blocks; // 已分配 512B 块个数
time_t st_atime; // 上次访问时间
time_t st_mtime; // 上次更新时间
time_t st_ctime; // 上次状态更改时间
};
st_dev字段描述该文件所在的设备。(major() 和minor()宏可能在分析这个设备ID域时有用。)
st_rdev 字段描述这个文件(inode)本身代表的设备。
st_size字段 给出文件字节尺寸(如果它是一个普通文件或符号链接)。对于符号链接而言是它所有包含路径名长度,不包括结尾的空字符。
st_blocks 字段指明文件已经分配数据块的个数,数据块以 512 字节为单位。(这可能小于st_size/512,当文件有空洞时。)
st_blksize 给出对于高效文件系统 I/O 操作的优先块尺寸。(数据以小尺寸块写入文件时可能导致低效的读-更改-覆盖 操作。)
不是所有的 Linux 文件系统实现了所有的时间域。一些文件系统允许挂载时不去访问文件或目录且不会导致st_atime 字段更新。(参考 mount() 的noatime、nodiratime 和 relatime,以及mount() 中相关的信息。)此外,如果文件以O_NOATIME 标志打开,st_atime 不会被更新。
st_atime字段在文件访问时更改,比如,execve()、mknod()、pipe()、utime() 和read()(多于零个字节)。
域 st_mtime在文件更改时更新,比如,mknod()、truncate()、utime() 和write()(多于零个字节)。再者,一个目录的st_mtime在这个目录里创建或删除文件时更新。st_mtime 在更改所有者、组、硬链接个数或权限模式时 不会更新。
st_ctime 字段在写入或设置结点(inode)信息(如所有者、组、链接数、权限等等)时会更改。
struct stat {
mode_t st_mode; //文件对应的模式,文件,目录等
ino_t st_ino; //inode节点号
dev_t st_dev; //设备号码
dev_t st_rdev; //特殊设备号码
nlink_t st_nlink; //文件的连接数
uid_t st_uid; //文件所有者
gid_t st_gid; //文件所有者对应的组
off_t st_size; //普通文件,对应的文件字节数
time_t st_atime; //文件最后被访问的时间
time_t st_mtime; //文件内容最后被修改的时间
time_t st_ctime; //文件状态改变时间
blksize_t st_blksize; //文件内容对应的块大小
blkcnt_t st_blocks; //伟建内容对应的块数量
};
#include <unsitd.h>
#inlcude <sys/stat.h>
#include <sys/types.h>
int fstat(int filedes,struct stat *buf);
int stat(const char *path,struct stat *buf);
int lstat(const char *path,struct stat *buf);
这三个系统调用都可以返回指定文件的状态信息,这些信息被写到结构struct stat的缓冲区中。通过分析这个结构可以获得指定文件的信息。
void report(struct stat *ptr)
{
printf("The major device no is:%d\n",major(ptr->st_dev));//主设备号
printf("The minor device no is:%d\n",minor(ptr->st_dev));//从设备号
printf("The file's node number is:%d\n",ptr->st_ino);//文件节点号
printf("The file's access mode is:%d\n",ptr->st_mode);//文件的访问模式
printf("The file's hard link number is:%d\n",ptr->st_nlink);//文件的硬链接数目
printf("The file's user id is:%d\n",ptr->uid);//文件拥有者的ID
printf("The file's group id is:%d\n",ptr->gid);//文件的组ID
printf("The file's size is:%d\n",ptr->st_size);//文件的大小
printf("The block size is:%d\n",ptr->blksize);//文件占用的块数量
printf("The number of allocated blocks is:%d\n",ptr->st_blocks);//文件分配块数量
struct tm*accesstime,*lmodifytime,*lchangetime;//访问时间,修改时间,最后一个改变时间(属性)
accesstime=localtime(&(ptr->st_atime));
accesstime=localtime(&(ptr->st_mtime));
accesstime=localtime(&(ptr->st_ctime));
printf("The last access time is: %d::%d::%d\n",accesstime->hour,accesstime->min,accesstime->sec);
printf("The last modify time is:%d::%d::%d\n",lmodifytime->hour,lmodifytime->min,lmodifytime->sec);
printf("The last change time is:%d::%d::%d\n",lchangetime->hour,lchangetime->min,lchangetime->sec);
}
结构time_t可用用localtime转换成tm结构,获得本地时间。
学习记录
遇到问题
1.运行ls1的时候,出现了在上面图片中“bash: ./: 是一个目录”
解决:通过检查发现在./中多加了一个空格
参考资料
1.Linux中的ls命令详细使用 - ansha886的专栏 - 博客频道 - CSDN.NET
http://blog.csdn.net/ansha886/article/details/4426103
2.编写who命令--从Linux中学习Linux - Orisun - 博客园
http://www.cnblogs.com/zhangchaoyang/articles/2293657.html
3.Linux命令学习总结: file命令 - 潇湘隐者 - 博客园
http://www.cnblogs.com/kerrycode/p/3806618.html