ls命令的简单实现
ls命令的简单实现
目标:简单的实现ls命令
实现的mic_ls命令主要功能
1.循环遍历目录
2.列出目标目录所有的子目录和文件
3.列出文件的文件权限,所有者,文件大小等详细信息
参数
-r 循环遍历
-a 列出全部文件
-l 列出详细信息(文件类型、权限。。。)
环境
ubuntu 14.04 gcc.real (Ubuntu 4.8.2-19ubuntu1) 4.8.2
代码
新手菜鸟 如有错误 欢迎指正
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdbool.h>
#include<dirent.h>
#include<string.h>
#include<sys/stat.h>
#include<pwd.h>
#include<grp.h>
bool show_all=false;
bool show_list=false;
bool show_recursion=false;
void do_ls_r(char *pathname,int depth);
void do_ls(char *pathname);
int judge_dir(char *pathname);
void do_showlist(DIR *dp);
void mode_to_letters(int mode,char str[]);
char *uid_to_name(uid_t uid);
char *gid_to_name(gid_t gid);
int main(int argc,char *argv[])
{
int opt;
while((opt=getopt(argc,argv,"arl"))!=-1){
switch(opt){
case 'a':
show_all=true;
break;
case 'r':
show_recursion=true;
break;
case 'l':
show_list=true;
break;
case '?':
printf("unknow option :%c\n",optopt);
exit(1);
}
}
if(show_recursion){
if(argc==optind)
do_ls_r(".",4);
else{
for(;optind<argc;optind++){
if(judge_dir(argv[optind])){
printf("%s:\n",argv[optind]);
do_ls_r(argv[optind],4);
}
else{
printf("not a directory!\n");
exit(1);
}
}
}
}
else{
if(argc==optind)
do_ls(".");
else{
for(;optind<argc;optind++){
if(judge_dir(argv[optind])){
printf("%s:\n",argv[optind]);
do_ls(argv[optind]);
}
else{
printf("not a directory!\n");
exit(1);
}
}
}
}
}
int judge_dir(char *pathname)
{
struct stat statbuf;
if((lstat(pathname,&statbuf))<0){
printf("error in lstat!\n");
exit(1);
}
if(S_ISDIR(statbuf.st_mode))
return 1;
else
return -1;
}
void do_ls_r(char *pathname,int depth)
{
DIR *dp;
struct dirent *entry;
struct stat statbuf;
if((dp=opendir(pathname))==NULL){
printf("can't open dir:%s\n",pathname);
exit(1);
}
chdir(pathname);
while((entry=readdir(dp))!=NULL){
lstat(entry->d_name,&statbuf);
if(S_ISDIR(statbuf.st_mode)){
if(strcmp(".",entry->d_name)==0||strcmp("..",entry->d_name)==0)
continue;
printf("%*s%s/\n",depth," ",entry->d_name);
do_ls_r(entry->d_name,depth+4);
}
else
printf("%*s%s\n",depth," ",entry->d_name);
}
chdir("..");
closedir(dp);
}
void do_ls(char *pathname)
{
DIR *dp;
struct dirent *entry;
if((dp=opendir(pathname))==NULL){
printf("can't open dir:%s\n",pathname);
exit(1);
}
if(show_list){
chdir(pathname);
do_showlist(dp);
}
else{
while((entry=readdir(dp))!=NULL){
if(!show_all)
if(*(entry->d_name)=='.')
continue;
printf("%s\n",entry->d_name);
}
closedir(dp);
}
}
void do_showlist(DIR *dp)
{
struct dirent *entry;
struct stat statbuf;
char l_mode[11];
while((entry=readdir(dp))!=NULL){
if((lstat(entry->d_name,&statbuf))<0){
printf("error :in lstat\n");
exit(1);
}
if(!show_all)
if(*(entry->d_name)=='.')
continue;
mode_to_letters(statbuf.st_mode,l_mode);
printf("%s",l_mode);
printf("%4d ",(int)statbuf.st_nlink);
printf("%-8s ",uid_to_name(statbuf.st_uid));
printf("%-8s ",gid_to_name(statbuf.st_gid));
printf("%8ld ",(long)statbuf.st_size);
printf(" %s ",entry->d_name);
printf("\n");
}
}
void mode_to_letters(int mode,char str[])
{
strcpy(str,"----------");
if(S_ISDIR(mode)) str[0]='d';
if(S_ISCHR(mode)) str[0]='c';
if(S_ISBLK(mode)) str[0]='b';
if(mode&S_IRUSR) str[1]='r';
if(mode&S_IWUSR) str[2]='w';
if(mode&S_IXUSR) str[3]='x';
if(mode&S_IRGRP) str[4]='r';
if(mode&S_IWGRP) str[5]='w';
if(mode&S_IXGRP) str[6]='x';
if(mode&S_IROTH) str[7]='r';
if(mode&S_IWOTH) str[8]='w';
if(mode&S_IXOTH) str[9]='x';
}
char *uid_to_name(uid_t uid)
{
struct passwd *getpwuid(),*pw_ptr;
if((pw_ptr=getpwuid(uid))!=NULL)
return (pw_ptr->pw_name);
else
return NULL;
}
char *gid_to_name(gid_t gid)
{
struct group *getgrid,*grp_ptr;
if((grp_ptr=getgrgid(gid))!=NULL)
return (grp_ptr->gr_name);
else
return NULL;
}
ls命令的简单实现的更多相关文章
- Linux系统编程_1_文件夹读取(实现简单ls命令)
闲来无事.随便写写,实现简单的ls命令: | 1 #include <stdio.h> | 2 #include <stdlib.h> | 3 #include <dir ...
- Linux/UNIX编程:使用C语言实现简单的 ls 命令
刚好把 Linux/UNIX 编程中的文件和IO部分学完了,就想编写个 ls 命令练习一下,本以为很简单,调用个 stat 就完事了,没想到前前后后弄了七八个小时,90%的时间都用在格式化(像 ls ...
- Linux命令系列之ls——原来最简单的ls这么复杂
Linux命令系列之ls--原来最简单的ls这么复杂 ls命令应该是我们最常用的命令之一了,但是我们可能容易忽略那些看起来最简单的东西. 简介 ls命令的使用格式如下 ls [选项] [具体的文件] ...
- linux下的ls命令
在LINUX系统中有一个重要的概念:一切都是文件.其实这是UNIX哲学的一个体现,而Linux是重写UNIX而来,所以这个概念也就传承了下来.在UNIX系统中,把一切资源都看作是文件,包括硬件设备.U ...
- Linux下ls命令显示符号链接权限为777的探索
Linux下ls命令显示符号链接权限为777的探索 --深入ls.链接.文件系统与权限 一.摘要 ls是Linux和Unix下最常使用的命令之一,主要用来列举目录下的文件信息,-l参数允许查看当前目录 ...
- ls命令的20个实用范例
contents ls -l -h -lhS -l --block-size=M -a -d */ -g -G -n --color=never -i -p -r -R -t ls ~ ls --ve ...
- linux ls 命令
ls 命令是 Linux 下最常用的命令之一,用来查询目录下的内容(list directory contents).本文将介绍其基本的用法和一些典型的用例.笔者使用的测试环境为 ubuntu 16. ...
- shell的 ls命令
Linux下shell 的 ls 命令 ls -d 显示当前目录的上层目录,不显示子目录 ls -a 显示当前目录下的所有子目录,包括隐藏的文件 ls -l 显示当前目录下所有文件的所有信息(除隐藏文 ...
- Hadoop Ls命令添加显示条数限制參数
前言 在hadoop的FsShell命令中,预计非常多人比較经常使用的就是hadoop fs -ls,-lsr,-cat等等这种与Linux系统中差点儿一致的文件系统相关的命令.可是细致想想,这里还是 ...
随机推荐
- MyBatis之Oracle、Mysql批量插入
Mybatis中Dao层 public interface UsersMapper { public void insertEntitys(List<UserEntity> users); ...
- Android笔记(四十) Android中的数据存储——SQLite(二) insert
准备工作: 我们模拟一个注册的页面,先看UI 我们需要创建一个数据库:user,数据库包含表user,user表包含字段id.username.password.mobilephone MainAct ...
- 学习python的日常3
python的一些高级特性: 切片(跟名字一样,把一个完整的东西选取一部分自己想要的去切下来):通过切片可以快速的去除一些元素,只要确定好索引位置,避免的循环导致的多写代码 数组,元组,字符串都可以用 ...
- CentOS上使用ntfs-3g挂载NTFS分区
U盘做过系统盘,是NTFS格式的,Centos7竟然不识别,而且因为一些原因,我的服务器没有联网,只能用U盘 查过资料才知道Centos7上默认是不支持挂载NTFS格式的分区的,需要安装ntfs-3g ...
- 迷你商城后台管理系统————stage2核心代码实现
应用程序主函数接口 @SpringBootApplication(scanBasePackages = {"org.linlinjava.litemall.db", "o ...
- 分布式结构化存储系统-HBase访问方式
分布式结构化存储系统-HBase访问方式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. HBase提供了多种访问方式,包括HBase shell,HBase API,数据收集组件( ...
- SonarQube中三种类型的代码规则
https://www.cnblogs.com/guoguochong/p/9117829.html 1.概述SonarQube(sonar)是一个 开源 平台,用于 管理 源代码的 质量 . Son ...
- 微信小程序API~检查登录状态
wx.checkSession(Object object) 检查登录态是否过期. 通过 wx.login 接口获得的用户登录态拥有一定的时效性.用户越久未使用小程序,用户登录态越有可能失效.反之如果 ...
- c++ default关键字
PicServer() = default; ~PicServer() = default; CString 似乎也可以写出来, https://blog.csdn.net/a1875566250 ...
- vbs读取TXT每一行并赋值到变量a
vbs代码: Dim fso,f,a Set fso = CreateObject("Scripting.FileSystemObject") Set f=fso.OpenText ...