仓酷云
标题:
Linux制作之编写who命令--从Linux中进修Linux仓酷云
[打印本页]
作者:
不帅
时间:
2015-1-18 11:29
标题:
Linux制作之编写who命令--从Linux中进修Linux仓酷云
有些人号称用过十几种甚至几十种linux,向人谈论起来头头是到,好像懂的很多。
实行who命令检察已登录的用户信息
$who
orisuntty72011-12-1914:12(:0)
orisunpts/02011-12-1914:12(:0.0)
显现出了:用户名、终端名、登录工夫、登录地点
如今我们要本人写一个程序来完成who。是否是要用到一些特别的体系挪用,大概必要root权限呢?实践上都不必,我们要学会利用Linux的联机匡助文档,从Linux中进修Linux。
要进修linux体系给我们供应的编程接口,良多工夫检察响应的头文件就能够了。
$manwho
WHO(1)UserCommandsWHO(1)
NAME
who-showwhoisloggedon
SYNOPSIS
who[OPTION]...[FILE|ARG1ARG2]
DESCRIPTION
Printinformationaboutuserswhoarecurrentlyloggedin.
-a,--all
sameas-b-d--login-p-r-t-T-u
-b,--boot
timeoflastsystemboot
-d,--dead
……
注重我白色标出的谁人1是大节编号。利用who命令时能够指定FILE,在who的DESCRIPTION中有这么几行字:IfFILEisnotspecified,use/var/run/utmp./var/log/wtmpasFILEiscommon.实践上who是经由过程读取/var/run/utmp文件来猎取已登录的用户信息的。
带有选项-k的man命令能够依据关头字来搜刮联机匡助。
$man-kutmp
endutent(3)-accessutmpfileentries
endutxent(3)-accessutmpfileentries
getutent(3)-accessutmpfileentries
getutent_r(3)-accessutmpfileentries
getutid(3)-accessutmpfileentries
getutid_r(3)-accessutmpfileentries
getutline(3)-accessutmpfileentries
getutline_r(3)-accessutmpfileentries
getutmp(3)-copyutmpstructuretoutmpx,andviceversa
getutmpx(3)-copyutmpstructuretoutmpx,andviceversa
getutxent(3)-accessutmpfileentries
getutxid(3)-accessutmpfileentries
getutxline(3)-accessutmpfileentries
login(3)-writeutmpandwtmpentries
logout(3)-writeutmpandwtmpentries
pututline(3)-accessutmpfileentries
pututxline(3)-accessutmpfileentries
sessreg(1)-manageutmp/wtmpentriesfornon-initclients
setutent(3)-accessutmpfileentries
setutxent(3)-accessutmpfileentries
utmp(5)-loginrecords
utmpname(3)-accessutmpfileentries
utmpx(5)-loginrecords
utmpxname(3)-accessutmpfileentries
这里的“5”是大节编号。
$man5utmp UTMP(5)LinuxProgrammersManualUTMP(5)
NAME
utmp,wtmp-loginrecords
SYNOPSIS
#include<utmp.h>
DESCRIPTION
Theutmpfileallowsonetodiscoverinformationaboutwhoiscurrentlyusingthesystem.Theremaybemoreuserscurrentlyusingthesystem,becausenotallprogramsuseutmplogging.
……
/*Valuesforut_typefield,below*/
#defineEMPTY0/*Recorddoesnotcontainvalidinfo(formerlyknownasUT_UNKNOWNonLinux)*/
#defineRUN_LVL1/*Changeinsystemrun-level(seeinit(8))*/
#defineBOOT_TIME2/*Timeofsystemboot(inut_tv)*/
#defineNEW_TIME3/*Timeaftersystemclockchange(inut_tv)*/
#defineOLD_TIME4/*Timebeforesystemclockchange(inut_tv)*/
#defineINIT_PROCESS5/*Processspawnedbyinit(8)*/
#defineLOGIN_PROCESS6/*Sessionleaderprocessforuserlogin*/
#defineUSER_PROCESS7/*Normalprocess*/
#defineDEAD_PROCESS8/*Terminatedprocess*/
#defineACCOUNTING9/*Notimplemented*/
#defineUT_LINESIZE32
#defineUT_NAMESIZE32
#defineUT_HOSTSIZE256
structexit_status{/*Typeforut_exit,below*/
shortinte_termination;/*Processterminationstatus*/
shortinte_exit;/*Processexitstatus*/
};
structutmp{
shortut_type;/*Typeofrecord*/
pid_tut_pid;/*PIDofloginprocess*/
charut_line[UT_LINESIZE];/*Devicenameoftty-"/dev/"*/
charut_id[4];/*Terminalnamesuffix,orinittab(5)ID*/
charut_user[UT_NAMESIZE];/*Username*/
charut_host[UT_HOSTSIZE];/*Hostnameforremotelogin,orkernelversionforrun-levelmessages*/
structexit_statusut_exit;/*ExitstatusofaprocessmarkedasDEAD_PROCESS;notusedbyLinuxinit(8)*/
/*Theut_sessionandut_tvfieldsmustbethesamesizewhencompiled32-and64-bit.Thisallowsdatafilesandsharedmemorytobesharedbetween32-and64-bitapplications.*/
#if__WORDSIZE==64&&defined__WORDSIZE_COMPAT32
int32_tut_session;/*SessionID(getsid(2)),usedforwindowing*/
struct{
int32_ttv_sec;/*Seconds*/
int32_ttv_usec;/*Microseconds*/
}ut_tv;/*Timeentrywasmade*/
#else
longut_session;/*SessionID*/
structtimevalut_tv;/*Timeentrywasmade*/
#endif
int32_tut_addr_v6[4];/*Internetaddressofremotehost;IPv4addressusesjustut_addr_v6[0]*/
char__unused[20];/*Reservedforfutureuse*/
};
/*Backwardscompatibilityhacks*/
#defineut_nameut_user
#ifndef_NO_UT_TIME
#defineut_timeut_tv.tv_sec
#endif
#defineut_xtimeut_tv.tv_sec
#defineut_addrut_addr_v6[0]
……
#include<stdio.h>#include<utmp.h>#include<string.h>#include<stdlib.h>#defineSHOWHOSTvoidshow_info(structutmp*);intmain(){structutmprecord;FILE*fp;intstrulen=sizeof(record);if((fp=fopen("/var/run/utmp","r"))==0){//翻开文件perror("fopen");exit(0);}memset(&record,0x00,strulen);while(fread(&record,strulen,1,fp)){//轮回读取纪录(布局体)show_info(&record);}fclose(fp);//封闭文件return0;}voidshow_info(structutmp*buf){printf("%-8s",buf->ut_name);//输入用户名printf("%-8s",buf->ut_line);//终端设备名printf("%10ld",buf->ut_time);//登录工夫#ifdefSHOWHOSTprintf("(%s)",buf->ut_host);#endifprintf("
");}
复制代码
运转了局:$./who1
reboot~1324275122(2.6.38-13-generic)
runlevel~1324275122(2.6.38-13-generic)
LOGINtty41324275122()
LOGINtty51324275122()
LOGINtty21324275122()
LOGINtty31324275122()
LOGINtty61324275122()
LOGINtty11324275128()
orisuntty71324275138(:0)
orisunpts/01324275175(:0.0)
orisunpts/11324285820(:0.0)
下面的程序有两个成绩:
工夫显现的是time_t范例的,方便于浏览
utmp文件不但包括举动用户的信息,连那些还没有用到的终端信息也保留在utmp文件。
办理成绩1。让我们找一下和工夫格局转换相干的函数。
$man-ktime|grep-itransform
asctime(3)-transformdateandtimetobroken-downtimeorASCII
asctime_r(3)-transformdateandtimetobroken-downtimeorASCII
ctime(3)-transformdateandtimetobroken-downtimeorASCII
ctime_r(3)-transformdateandtimetobroken-downtimeorASCII
gmtime(3)-transformdateandtimetobroken-downtimeorASCII
gmtime_r(3)-transformdateandtimetobroken-downtimeorASCII
localtime(3)-transformdateandtimetobroken-downtimeorASCII
localtime_r(3)-transformdateandtimetobroken-downtimeorASCII
mktime(3)-transformdateandtimetobroken-downtimeorASCII
好,我们细心浏览一下localtime
$manlocaltime
CTIME(3)LinuxProgrammersManualCTIME(3)
NAME
asctime,ctime,gmtime,localtime,mktime,asctime_r,ctime_r,gmtime_r,localtime_r-transformdateandtimeto
broken-downtimeorASCII
SYNOPSIS
#include<time.h>
char*asctime(conststructtm*tm);
char*asctime_r(conststructtm*tm,char*buf);
char*ctime(consttime_t*timep);
char*ctime_r(consttime_t*timep,char*buf);
structtm*gmtime(consttime_t*timep);
structtm*gmtime_r(consttime_t*timep,structtm*result);
structtm*localtime(consttime_t*timep);
structtm*localtime_r(consttime_t*timep,structtm*result);
time_tmktime(structtm*tm);
FeatureTestMacroRequirementsforglibc(seefeature_test_macros(7)):
asctime_r(),ctime_r(),gmtime_r(),localtime_r():
_POSIX_C_SOURCE>=1||_XOPEN_SOURCE||_BSD_SOURCE||_SVID_SOURCE||_POSIX_SOURCE
DESCRIPTION
Thectime(),gmtime()andlocaltime()functionsalltakeanargumentofdatatypetime_twhichrepresentscalendar
time.Wheninterpretedasanabsolutetimevalue,itrepresentsthenumberofsecondselapsedsincetheEpoch,
1970-01-0100:00:00+0000(UTC).
Theasctime()andmktime()functionsbothtakeanargumentrepresentingbroken-downtimewhichisarepresentation
separatedintoyear,month,day,etc.
Broken-downtimeisstoredinthestructuretmwhichisdefinedin<time.h>asfollows:
structtm{
inttm_sec;/*seconds*/
inttm_min;/*minutes*/
inttm_hour;/*hours*/
inttm_mday;/*dayofthemonth*/
inttm_mon;/*month*/
inttm_year;/*year*/
inttm_wday;/*dayoftheweek*/
inttm_yday;/*dayintheyear*/
办理成绩2。经由过程浏览utmp.h我们发明,utmp布局中有一个成员ut_type,当它的值为7(USER_PROCESS)时,暗示这个用户已登录。
综上所述,我们给出改善后的代码。
#include<stdio.h>
#include<utmp.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#defineSHOWHOST
voidshow_info(structutmp*);
intmain(){
structutmprecord;
FILE*fp;
intstrulen=sizeof(record);
if((fp=fopen("/var/run/utmp","r"))==0){//翻开文件
perror("fopen");
exit(0);
}
memset(&record,0x00,strulen);
while(fread(&record,strulen,1,fp)){//轮回读取纪录(布局体)
show_info(&record);
}
fclose(fp);//封闭文件
return0;
}
voidshow_info(structutmp*buf){
if(buf->ut_type!=USER_PROCESS)//非登任命户
return;
printf("%-8s",buf->ut_name);//输入用户名
printf("%-12s",buf->ut_line);//终端设备名
time_ttimelong=buf->ut_time;
structtm*localnow=localtime(&timelong);
printf("%d-%d-%d%d:%d",localnow->tm_year+1990,localnow->tm_mon+1,localnow->tm_mday,localnow->tm_hour,localnow->tm_min);//登录工夫
#ifdefSHOWHOST
printf("(%s)",buf->ut_host);
#endif
printf("
");
}
登录/注册后可看大图
234625IR-0.png
(16.76 KB, 下载次数: 8)
下载附件
保存到相册
Linux制作之编写who命令--从Linux中进修Linux仓酷云
2015-1-18 11:29 上传
<br>
在linux中学习命令的最好办法是学习Shell脚本编程,Shell脚本比起其他语言来学习简单,但是功能却十分强大.通过学习Shell编程,能让你掌握大量的linux命令。
作者:
乐观
时间:
2015-1-21 07:46
我们这一代90后,从小接触的是windows98,家里条件好的自己有电脑装的是2000,后来又有了XP,上大学时又有了win7。
作者:
山那边是海
时间:
2015-1-22 20:03
永中office 2004增强版安装只需要默认安装即可使用并操作大多与win系统雷同,打印机的配置和管理,记录光盘等。
作者:
飘飘悠悠
时间:
2015-1-31 10:46
永中office 2004增强版安装只需要默认安装即可使用并操作大多与win系统雷同,打印机的配置和管理,记录光盘等。
作者:
再现理想
时间:
2015-2-2 22:07
为了更好的学习这门课程,我不仅课上认真听讲,课下也努力学习,为此还在自己的电脑上安装了Ubuntu系统。
作者:
飘灵儿
时间:
2015-2-7 12:00
在系统检测不到与Linux兼容的显卡,那么此次安装就可能不支持图形化界面安装,而只能用文本模式安装等等。
作者:
admin
时间:
2015-2-21 20:37
Linux高手更具有鼓励新手的文化精神。如何在Linux社区获得帮助,需要说明的是你要有周全的思考,准备好你的问题,不要草率的发问。
作者:
老尸
时间:
2015-3-5 20:55
用户下达的命令解释给系统去执行,并将系统传回的信息再次解释给用户,估shell也称为命令解释器,有关命令的学习可参考论坛相关文章,精通英文也是学习Linux的关键。
作者:
若天明
时间:
2015-3-7 10:32
选择交流平台,如QQ群,网站论坛等。
作者:
灵魂腐蚀
时间:
2015-3-11 10:23
Linux只是个内核!这点很重要,你必须理解这一点。只有一个内核是不能构成一个操作系统的。
作者:
柔情似水
时间:
2015-3-18 04:39
目前全球有超过一百多个Linux发行版本,在国内也能找到十几个常见版本。如何选择请根据你的需求和能力,RedhatLinux和DebianLinux是网络管理员的理想选择。
作者:
简单生活
时间:
2015-3-25 11:36
下面笔者在论坛看到的一个好问题: “安装红旗4.0后,系统紫光输入法自带的双拼方案和我的习惯不一样,如何自定义双拼方案解决?谢谢?”这个问题很简练。
欢迎光临 仓酷云 (http://ckuyun.com/)
Powered by Discuz! X3.2