生活资讯
lstat 、老鼠图案图片
2023-04-07 02:02  浏览:50

LINUX中ls -l是如何工作的?如何去实现一个脚本?

可以参考:

#include

sys/types.h

#include

sys/stat.h

#include

unistd.h

#include

stdio.h

#include

string.h

#include

errno.h

#include

pwd.h

#include

grp.h

#include

time.h

#include

dirent.h

int

do_ls(char

*dir,char

*filename,int

lflag)

{

int

n;

struct

stat

buf;

char

out[100];

struct

passwd

*pw;

struct

group

*gr;

struct

tm

*t;

if(lflag

==

0)

//如果不带l参数,直接显示文件/目录名

{

printf("%st",filename);

return

0;

}

if(lstat(dir,buf)0)

{

fprintf(stderr,"stat

error:%sn",strerror(errno));

return

-1;

}

switch(buf.st_mode

s_ifmt)

//获取字符串的属性:普通文件-、目录d、字符设备c、块设备b、管道文件p、连接文件l、套接字文件s

{

case

s_ifreg:

printf("-");

break;

case

s_ifdir:

printf("d");

break;

case

s_ifchr:

printf("c");

break;

case

s_ifblk:

printf("b");

break;

case

s_ififo:

printf("p");

break;

case

s_iflnk:

printf("l");

break;

case

s_ifsock:

printf("s");

break;

}

for(n=8;n=0;n--)

//打印文件的读写属性:读r、写w、执行x、无权限-

{

if(buf.st_mode(1n))

{

switch(n%3)

{

case

2:

printf("r");

break;

case

1:

printf("w");

break;

case

0:

printf("x");

break;

def***lt:

break;

}

}

else

{

printf("-");

}

}

printf("

%d",buf.st_nlink);

//硬链接数,此链接非彼链接,指(包含)目录的个数,文件为1,目录起始为2,再加上目录里包含的目录个数(不递归,只一层)

pw

=

getpwuid(buf.st_uid);

//所属用户名

printf("

%s",pw-pw_name);

gr

=

getgrgid(buf.st_gid);

//所属组名

printf("

%s",gr-gr_name);

printf("

%ld",buf.st_size);

//字节计总大小

t

=

localtime(buf.st_atime);

//最后一次访问时间

printf("

%d-%d-%d

%d:%d"

,t-tm_year+1900

,t-tm_mon+1

,t-tm_md***

,t-tm_hour

,t-tm_min);

printf("

%s

",filename);

if(s_islnk(buf.st_mode))

//判断是否为链接,是返回真

{

printf("

-

");

if(readlink(filename,out,100)==-1)

{

//printf("readlink

errorn");

}

printf("%s",out);

}

printf("n");

return

0;

}

int

ls_prepare(char

*w,int

aflag,int

lflag)

//ls的准备工作

{

struct

stat

buf;

//man

lstat可以看到此结构

char

name[100];

dir

*dir;

//类似打开文件的fd描述符

struct

dirent

*pdr;

//man

readdir可以看到此结构

if(lstat(w,buf)0)

//获取文件/目录属性并赋值给buf,该函数和lstat一样,只是当w为链接时,指代他本身,并不存在文件

{

fprintf(stderr,"stat

error:%sn",strerror(errno));

return

-1;

}

if(s_isdir(buf.st_mode))

//判断是否为目录,是返回真

{

dir

=

opendir(w);

//打开目录

while

((pdr

=

readdir(dir))!=null)

//读/遍历目录

{

if(aflag==0)

//如果不带a参数,越过以.开头的所有文件/目录

{

if(pdr-d_name[0]=='.')

continue;

memset(name,0,100);

strcpy(name,w);

//拷贝

strcat(name,"/");

//追加

strcat(name,pdr-d_name);

do_ls(name,pdr-d_name,lflag);

}else

//有a参数显示所有

{

memset(name,0,100);

strcpy(name,w);

strcat(name,"/");

strcat(name,pdr-d_name);

do_ls(name,pdr-d_name,lflag);

}

}

closedir(dir);

}else

//为文件则直接显示

{

do_ls(w,w,lflag);

}

return

0;

}

int

main(int

argc,char

**argv)

{

int

aflag

=0;

int

lflag

=0;

char

c;

int

i;

while((c

=

getopt(argc,argv,"al"))!=-1)

//解析命令行参数,即-/--后面的字符串和给定的字符串匹配,有未解析字母返回字母或问号(取决于第3个参数),否则返回-1

{

switch(c)

//此处仅匹配a(所有)和l(列表),即只支持参数a、l

{

case

'a':

aflag

=1;

break;

case

'l':

lflag

=1;

break;

def***lt:

break;

}

}

if(argc

==

optind

)

//optind系统变量,执行命令参数的个数(不包括命令,奇怪的是无参情况下他为1),判断argc是否为1,是则取当前路径,让我们显得更专业点

{

ls_prepare("./",aflag,lflag);

}

else

{

for(i=optind;iargc;i++)

//所有目录都传进去

ls_prepare(argv[i],aflag,lflag);

}

printf("n");

return

0;

}

弱弱的问,WIN下是不是不能用lstat()函数

1、数据类型问题。首先要检查应用的目标列和被应用的目标列数据类型是否一致。如一个是文本,一个是数字,那结果肯定是报错,一个也匹配不出来。2、空格问题。需要检查套用的目标单元格的值前后是否有空格,尤其是从系统中导出的excel数据表时,特别要检查这一点。

3、目标套用列是否位于***列;这个不容赘述,这是vlookup函数最显著的特点。

4、第三个参数是否正确。即被套用的对象是第几列开始显示,这也是vlookup函数的基本含义。

5、明确第二个参数是绝对引用还是相对引用。

6、数据表是否存在合并单元格。如有,则还原。

7、注意是精确查找还是模糊匹配。

hi~你不知道的vim小秘密

大家先了解一些背景知识:

1) 给文件增加了i权限,那文件不能被更改,不能删除,也不能修改名字以及权限。

2) 给文件增加a权限,文件可以追加内容,不能删除,不能修改内容,不能修改名字以及权限。

3) vim一个文件,如果不正常退出,再次编辑时是会提示一些信息的,并且有一个隐藏的文件.xxx.swp

1) 如果给一个文件增加a权限,用vim编辑文件,增加内容(注意是在文件末尾增加内容,不要修改其他内容),并不会成功。

2) 如果给一个目录增加i权限或者a权限,在该目录下面vim一个文件,更改文件内容可以正常保存。

既然a权限可以追加内容,那为何vim一个文件在末尾增加内容不能成功?

既然i权限不能修改,那为何在目录里面变更文件内容却可以成功?

关于这两点,你有没有疑惑?下面我们来分析原因。

先不管i或者a权限,在一个没有i或者a权限的目录下,编辑一个没有i或者a权限的文件,用strace来查看其执行过程。

mkdir /tmp/test

strace vim /tmp/test/aminglinux.txt 2/tmp/vim.log

写入一个数字1,然后保存退出。再来查看vim.log的内容。

less /tmp/vim.log 

大部分内容你不用关心,只需要看这几行:

stat("/tmp/test/aminglinux.txt", 0x7fff072ecb10) = -1 ENOENT (No such file or directory)

access("/tmp/test/aminglinux.txt", W_OK) = -1 ENOENT (No such file or directory)

open("/tmp/test/aminglinux.txt", O_RDONLY) = -1 ENOENT (No such file or directory)

readlink("/tmp/test/aminglinux.txt", 0x7fff072eb360, 4095) = -1 ENOENT (No such file or directory)

open("/tmp/test/.aminglinux.txt.swp", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/tmp/test/.aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL, 0600) = 3

open("/tmp/test/.aminglinux.txt.swx", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/tmp/test/.aminglinux.txt.swx", O_RDWR|O_CREAT|O_EXCL, 0600) = 4

unlink("/tmp/test/.aminglinux.txt.swx") = 0

unlink("/tmp/test/.aminglinux.txt.swp") = 0

stat("/tmp/test/.aminglinux.txt.swp", 0x7fff072ec310) = -1 ENOENT (No such file or directory)

lstat("/tmp/test/.aminglinux.txt.swp", 0x7fff072ec3e0) = -1 ENOENT (No such file or directory)

lstat("/tmp/test/.aminglinux.txt.swp", 0x7fff072ec8a0) = -1 ENOENT (No such file or directory)

open("/tmp/test/.aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600) = 3

stat("/tmp/test/aminglinux.txt", 0x7fff072eac40) = -1 ENOENT (No such file or directory)

stat("/tmp/test/aminglinux.txt", 0x7fff072ebe20) = -1 ENOENT (No such file or directory)

stat("/tmp/test/aminglinux.txt", 0x7fff072eadf0) = -1 ENOENT (No such file or directory)

write(1, ""/tmp/test/aminglinux.txt"", 26) = 26

stat("/tmp/test/aminglinux.txt", 0x7fff072ec050) = -1 ENOENT (No such file or directory)

open("/tmp/test/aminglinux.txt", O_WRonLY|O_CREAT|O_TRUNC, 0666) = 4

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=2, ...}) = 0

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=2, ...}) = 0

unlink("/tmp/test/.aminglinux.txt.swp") = 0

看起来乱乱的,其实大概的过程就是vim  /tmp/test/aminglinux.txt时,先看有没有.aminglinux.txt.swp以及.aminglinux.txt.swx,因为这两个文件就是vim产生的临时文件,swp先产生,如果swp存在就产生第二个swx。写入的内容先存到swp里,当保存退出vim时,再把swp的内容存到aminglinux.txt里,最后删除掉swp文件。

有了这个认识之后,我们再来分析上面提到的现象1。如果文件给了a权限,那么在编辑该文件时,会产生swp文件,当保存退出时,swp文件内容会写入该文件,这相当于更改该文件,很线上a权限是不允许的。

再来分析现象2,按照我们的推测,如果目录给了a权限,增加文件没问题,也就是说产生swp或者swx文件没有问题,当然把swp或者swx内容写入到文件里时也不会有问题,但swp或者swx文件却不会被删除了,所以再次编辑文件时就会提示临时文件已经存在了。但这并不会影响修改文件内容。

如果给目录设置了i权限的话,vim编辑文件,要产生swp或swx肯定会出错啊,但为何依然能正常编辑文件? 下面继续用strace来分析一下。

chattr +i  /tmp/test

strace vim /tmp/test/aminglinux.txt 2 /tmp/vim.log 

看vim.log里面和aminglinux.txt相关的信息

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

access("/tmp/test/aminglinux.txt", W_OK) = 0

open("/tmp/test/aminglinux.txt", O_RDONLY) = 3

readlink("/tmp/test/aminglinux.txt", 0x7fff49efc6f0, 4095) = -1 EINVAL (Invalid argument)

open("/tmp/test/.aminglinux.txt.swp", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/tmp/test/.aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied)

stat("/tmp/test/.aminglinux.txt.swp", 0x7fff49efd6a0) = -1 ENOENT (No such file or directory)

lstat("/tmp/test/.aminglinux.txt.swp", 0x7fff49efd770) = -1 ENOENT (No such file or directory)

lstat("/tmp/test/.aminglinux.txt.swp", 0x7fff49efdc30) = -1 ENOENT (No such file or directory)

open("/tmp/test/.aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600) = -1 EACCES (Permission denied)

readlink("/tmp/test/aminglinux.txt", 0x7fff49efc6f0, 4095) = -1 EINVAL (Invalid argument)

open("/root/tmp/aminglinux.txt.swp", O_RDONLY) = -1 ENOTDIR (Not a directory)

open("/root/tmp/aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 ENOTDIR (Not a directory)

stat("/root/tmp/aminglinux.txt.swp", 0x7fff49efd6a0) = -1 ENOTDIR (Not a directory)

lstat("/root/tmp/aminglinux.txt.swp", 0x7fff49efd770) = -1 ENOTDIR (Not a directory)

lstat("/root/tmp/aminglinux.txt.swp", 0x7fff49efdc30) = -1 ENOTDIR (Not a directory)

open("/root/tmp/aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600) = -1 ENOTDIR (Not a directory)

readlink("/tmp/test/aminglinux.txt", 0x7fff49efc6f0, 4095) = -1 EINVAL (Invalid argument)

open("/var/tmp/aminglinux.txt.swp", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/var/tmp/aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL, 0600) = 4

open("/var/tmp/aminglinux.txt.swx", O_RDONLY) = -1 ENOENT (No such file or directory)

open("/var/tmp/aminglinux.txt.swx", O_RDWR|O_CREAT|O_EXCL, 0600) = 5

unlink("/var/tmp/aminglinux.txt.swx")   = 0

unlink("/var/tmp/aminglinux.txt.swp")   = 0

stat("/var/tmp/aminglinux.txt.swp", 0x7fff49efd6a0) = -1 ENOENT (No such file or directory)

lstat("/var/tmp/aminglinux.txt.swp", 0x7fff49efd770) = -1 ENOENT (No such file or directory)

lstat("/var/tmp/aminglinux.txt.swp", 0x7fff49efdc30) = -1 ENOENT (No such file or directory)

open("/var/tmp/aminglinux.txt.swp", O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW, 0600) = 4

chmod("/var/tmp/aminglinux.txt.swp", 0644) = 0

open("/tmp/test/aminglinux.txt", O_RDONLY) = 3

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

access("/tmp/test/aminglinux.txt", W_OK) = 0

write(1, ""aminglinux.txt"", 16)      = 16

stat("aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

access("aminglinux.txt", W_OK)          = 0

getxattr("aminglinux.txt", "system.posix_acl_access", 0x7fff49efd050, 132) = -1 ENODATA (No data available)

stat("aminglinux.txt", {st_mode=S_IFREG|0644, st_size=4, ...}) = 0

open("aminglinux.txt", O_WRonLY|O_CREAT|O_TRUNC, 0644) = 3

chmod("aminglinux.txt", 0100644)        = 0

setxattr("aminglinux.txt", "system.posix_acl_access", "x02x00x00x00x01x00x06x00xffxffxffxffx04x00x04x00xffxffxffxff x00x04x00xffxffxffxff", 28, 0) = 0

stat("/tmp/test/aminglinux.txt", {st_mode=S_IFREG|0644, st_size=6, ...}) = 0

unlink("/var/tmp/aminglinux.txt.swp")   = 0

我相信你可以看到Permission denied的提示,这是因为当前目录有i权限,不能增加文件,也就不能在当前目录下生成临时文件。当然,vim如果遇到这样的问题,它还是会“曲线救国”的,于是先找/root/tmp/,但是并没有该目录,只好继续找/var/tmp/,这个目录存在,所以就在这个目录里生成了临时文件(并不是隐藏的)。后面的操作就不用多说了。

既然vim可以在/var/tmp/下生成临时文件,自然也可以在已经设置了i权限的目录里编辑文件的,这样现象2也解释通了。上面罗嗦了这么多,其实我就想表达如下观点:

vim编辑文件时,会在该文件所在目录生成临时隐藏文件.swp和.swx,如果那目录不可写就会到/root/tmp/下或者/var/tmp/下生成临时文件(非隐藏),当编辑的文件保存后,临时文件删除。

lstat和stat函数有什么区别?

stat和lstat的区别:当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;而stat返回的是该链接指向的文件的信息。(似乎有些晕吧,这样记,lstat比stat多了一个l,因此它是有本事处理符号链接文件的,因此当遇到符号链接文件时,lstat当然不会放过。而 stat系统调用没有这个本事,它只能对符号链接文件睁一只眼闭一只眼,直接去处理链接所指文件)阻塞与非阻塞:举个例子,比如我去银行办理业务,可能选择排队等候,也可能取一个小纸条上面有我的号码,等到排到我这一号时由柜台的人通知我轮到我去办理业务了.

前者(排队等候)就是同步等待消息,而后者(等待别人通知)就是异步等待消息.在异步消息处理中,等待消息者(在这个例子中就是等待办理业务的人)往往注册一个回调机制,在所等待的事件被触发时由触发机制(在这里是柜台的人)通过某种机制(在这里是写在小纸条上的号码)找到等待该事件的人.简单点说:阻塞就是干不完不准回来,

非阻塞就是你先干,我现看看有其他事没有,完了告诉我一声。那就好比socket中 监听函数,一直等待客户端的连接,在这之前什么也不做,只在等,这就是阻塞。运用多线程处理,用一个线程在等,另外的线程处理事件,从而增加效率。多看网上的例子,做一下TCP与UDP的例子就清楚很多。

关于lstat和老鼠图案图片的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

发表评论
0评