模擬實現一個簡單的shell程序,實現一些簡單的命令

功能:
/////我把這個程序說明說發到另外一篇博客////////////////////
1、顯示當前所在目錄的路徑名(指令pwd)
2、列出指定目錄名中的所有目錄及文件(指令list)
3、改變當前工作目錄(指令chadir)
4、新建目錄(指令makedir)
5、刪除目錄(指令deldir)
6、退出命令解釋程序(指令exit)
7、重命名一個文件或目錄(指令rename)
8、複製一個已存在的文件(指令copy)
9、在指定的目錄及其子目錄中查找指定的文件,並輸出查找到的文件的絕對路徑(指令find)
10、輸入指令錯誤時會提示,並可以重新輸入

下面的代碼可以直接複製運行,筆者目前還未發現bug,每個功能封裝在一個函數中,可以單個取出使用運行參考慢慢理解;

**用到的系統函數:**open(),close(),read(),write(),chdir(),opendir(),readdir(),closedir(),rmdir(),mkdir(),getcwd();

代碼如下(尾端有詳細一點的代碼解析,不懂可以評論或私聊):

#include"stdio.h"
#include"string.h"
#include"unistd.h"
#include"string.h"
#include"sys/types.h"
#include"sys/stat.h"
#include"stdlib.h"
#include"dirent.h"
#include"stddef.h"
#include"fcntl.h"
///////////////////////////////////////////////////////
void pwd_();
void makedir_();
void deldir_();
void exit_();
void chadir_();
void list_();
void rename_();
void copy_();
void find_();
void error_();
////////////////////////////////////////////////////
#define buffsize 1024

int main(void)
{
	char command[30];
while(1)
{	
	printf("Liangfenkai@");
	scanf("%s",command);
	fflush(stdin);
	if(strcmp(command,"pwd")==0)	
	{
	pwd_();
	}
	else if(strcmp(command,"makedir")==0)  
	{
	makedir_();
	}
	else if(strcmp(command,"deldir")==0) 	
	{
	deldir_();
	}
	else if(strcmp(command,"exit")==0)
	{
	exit_();
	}
	else if(strcmp(command,"chadir")==0) 
	{
	chadir_();
	}
	else if((strcmp(command,"list")==0))
	{
	list_();
	}
	else if(strcmp(command,"rename")==0)	
	{
	rename_();
	}
	else if(strcmp(command,"copy")==0)	
	{
	copy_();
	}
	else if(strcmp(command,"find")==0)	
	{
	find_();
	}
	else 		
	error_();
}
return 0;
}

//打印當前覺得路徑//////////////////////////////////////////////////////////////////////////
void pwd_()
{
     char *path=NULL;
	 path=getcwd(NULL,0);
     puts(path);
     free(path);
}
//創建文件夾/////////////////////////////////////////////////////////////////////////
void makedir_()
{
	char command1[30];
	scanf("%s",command1);
    fflush(stdin);
    if(mkdir(command1,0755)!=0)     
    printf("make dir default!\n");
}
//刪除文件夾////////////////////////////////////////////////////////////////////////
void deldir_()
{
	char command2[30];
	scanf("%s",command2);
    fflush(stdin);
    if(rmdir(command2)!=0)
    printf("delete dir default!\n");
}
//退出程序//////////////////////////////////////////////////////////////////////////
void exit_()
{
	exit(0);
}
//改變目錄路徑///////////////////////////////////////////////////////////////////////
void chadir_()
{
	char command3[50];
    scanf("%s",command3);
    fflush(stdin);
    if(chdir(command3)!=0)
    {
              printf("change dir path default!\n");
    }
}
//列出指定目錄名中的所有目錄及文件///////////////////////////////////////////////////////////////////////
void list_()
{
	char command4[50];
	struct dirent *entry;
	DIR *olist=NULL;
	int i=1;
	scanf("%s",command4);
    fflush(stdin);
    if((olist=opendir(command4))==NULL)
    {
        printf("opendir  default!\n");
    }
    while(entry=readdir(olist))
    {
        printf("file%d:%s\n",i,entry->d_name);
        i++;
     }
     i=1;
     if(closedir(olist)!=0)
     printf("closedir  default!\n");
}
//重命名一個文件或目錄///////////////////////////////////////////////////////////
void rename_()
{
	char newname[30],oldname[30];
	 printf("pleace input the old name:");
     scanf("%s",oldname);
     fflush(stdin);
     printf("pleace input the new name:");
     scanf("%s",newname);
     fflush(stdin);
     if(rename(oldname,newname)!=0)
     {
       printf("change name default!");
     }
}
//複製一個已存在的文件///////////////////////////////////////////////////////////////////////////
void copy_()
{
	char cp1[30],cp2[30],buf[buffsize];
	int fd1,fd2;
	int n;
	printf("pleace input the file be copy:\n");
    scanf("%s",cp1);
    fflush(stdin);
    printf("pleace input the new file name:\n");
    scanf("%s",cp2);
    if((fd1=open(cp1,O_RDWR|O_CREAT,0664))==-1)
        printf("open the file false!\n");
    if((n=read(fd1,buf,buffsize))==-1)
        printf("read the file false!\n");
    if((fd2=open(cp2,O_RDWR|O_CREAT,0664))==-1)
        printf("open the file false!\n");
    if(write(fd2,buf,n)==-1)
        printf("open the file false!\n");
     if(close(fd1)==-1)
        printf("close false!\n");
     if(close(fd2)==-1)
        printf("close false!\n");
}
//在指定的目錄及其子目錄中查找指定的文件,並輸出查找到的文件的絕對路徑///////////////
void find_()
{
	char *path1;
    char str1[30],str2[30];
    struct dirent *re;
	int j=0;
	DIR *dir;
	scanf("%s",str1);
    fflush(stdin);
    scanf("%s",str2);
    fflush(stdin);
    if((dir=opendir(str1))==NULL)
       printf("open dir error!\n");
    while((re=readdir(dir))!=NULL)
    {
       if(strcmp(re->d_name,str2)==0)
        {
         chdir(str1);
         path1=getcwd(NULL,0);
         puts(path1);
         chdir("..");
         j=1;
        }
     }
     if(j==0)
     {
     printf("no the file!\n");
     }
}
//輸入指令錯誤時會提示,並可以重新輸入//////////////////////////////////////////////////////////////////////
void error_()
{
	printf("input default!\n");
}



(1)strcmp()原型爲:int strcmp(const char *str1, const char *str2)作用是:比較字符串str1與str2,若str1>str2則返回值大於0,str1==str2返回值等於0,str1<str2返回值小於0;

(2)void pwd_()主要調用了getcwd()函數,其原型爲char *getcwd(char *buf,size_t size),該函數會將當前工作目錄的絕對路徑複製到參數buffer所指的內存空間中,參數size爲buf的空間大小。成功返回指向buf的指針,失敗返回-1;作用打印當前絕對路徑。

(3)void makedir_()主要調用int mkdir(const char *pathname,mode_t mode);*pathname是要創建目錄名稱(程序用char command1[30]),mode是目錄權限,該程序用0755,意爲擁有者可讀可寫可執行,而羣組或其他人只能讀跟執行,創建成功返回0,失敗返回-1。作用創建新文件夾

(4)void exit_()裏直接調用函數exit(0),意爲系統正常退出,要是exit(1)則爲錯誤退出。作用退出程序

(5)void deldir_()主要調用了int rmdir(const char *pathname);pathname爲刪除的目錄(程序用char command2[30),可以是絕對路徑及目錄名,成功刪除返回0,失敗返回-1.作用刪除目錄

(6)void chadir_()主要調用int chdir(const char * path);path是路徑(程序用char command3[50];),成功返回0,失敗返回-1,作用改變當前路徑

(7)void list_()主要調用DIR * opendir(const char * name),struct dirent * readdir(DIR * dir);int closedir(DIR *dir);其中name表示要打開的文件名(程序用char command4[50];),成功則返回DIR* 型態的目錄流,打開失敗則返回NULL(程序用DIR *olist=NULL;)。dir爲DIR* 型態的目錄流,程序中指向olist指向的地址,成功則返回下個目錄進入點。有錯誤發生或讀取到目錄文件尾則返回NULL(程序用struct dirent *entry;)。而完成上述操作後就關閉參數olist所指的目錄流(用closedir(olist)),關閉成功則返回0,失敗返回-1;作用列出指定目錄名中的所有目錄及文件;

(8)void rename_()主要調用int rename(char * oldname, char * newname);其中oldname是舊文件名,newname是新文件名(程序用char newname[30],oldname[30];),修改成功返回0,失敗返回-1,作用修改文件名

(9)void copy_()主要調用int open(const char *pathname,int flags,int perms),int close(int fd),ssize_t read(int fd, void *buf, size_t count),ssize_t write(int fd, void *buf, size_t count),其中pathname是要打開的文件名(程序用char cp1[30]),flags是文件權限(程序用O_RDWR|O_CREAT,意爲讀寫方式打開文件,如果改文件不存在,就創建一個新的文件,並用第三個參數爲其設置權限),則 perms也是設置權限的(程序中值是0664,意爲八進制,擁有者,羣組人員可讀可寫,其他人只能讀),成功返回文件描述符,失敗返回-1(程序用int fd1,fd2)。read()中fd也是文件描述符,把讀到的字符存到buf中,count是讀到的字節數,成功返回讀到的字節數,失敗返回-1(程序用int n)。write()中fd也是文件描述符,把數據來源爲 buf,count是寫入的字節數,成功返回寫入的字節數,失敗返回-1。close()中fd也是文件描述符,關閉成功返回0,失敗返回-1.作用複製一個已存在的文件 (char cp1[30],cp2[30])。

(10)void find_()主要調用了gets(),strcmp(),int chdir(const char *path ),char *getcwd(char *buf,size_t size),DIR * opendir(const char * name),struct dirent * readdir(DIR * dir);int closedir(DIR *dir);用到的變量char *path1;char str1[30],str2[30];struct dirent *re;int j=0;DIR *dir;該函數的實現是利用上述多個函數互相配合完成的,用opendir,readdir掃描目錄及其子目錄中查找指定的文件,用strcmp()比較與文件匹配是否一致,一致就用chdir()轉入目錄,再用getcwd()獲取當前絕對路徑,然後在利用chdir()返回原來的路徑,若輸入出錯會有提示,用int j標誌,當j==0時,就錯誤。作用在指定的目錄及其子目錄中查找指定的文件,並輸出查找到的文件的絕對路徑。

(11)void error_()函數是輸出命令錯誤時打印出input default!提示。作用提示輸入錯誤
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章