利用linux下的c語言程式設計來簡單的實現一個shell功能實現!
學習了fork(),exec()函式之後,讓我們來簡單是實現來實現一個shell
裡面用到了一些函式,進行對字串進行做一下簡單的處理!
#include<stdio.h>
#include<errno.h>
#include<sys/types.h>
#include<unistd.h>
#include<string.h>
#include<sys/wait.h>
#include<stdlib.h>
#include<pwd.h>
#define NUM 1024
#define SIZE 50
int mystrtok(char *argv[],char *string);
//這個函式做的是對字串的分割,把命令分割開,用到了字串的分割函式
int mystrtok(char *argv[],char *string)
{
int i=0;
char delim[]=" ";
char *p;
argv[0]=strtok(string,delim);//字串分割函式的使用
//printf("%s\n",argv[0]);
while(argv[i]!=NULL)
{
argv[++i]=strtok(NULL,delim);
//printf("%s is %d\n",argv[i],i);
}
return 0;
}
//獲得一個命令提示符的字串
char *getusername(char buffer[NUM])
{
uid_t userid;
char *username;
char *hostname;
char *ptr,*p;
char buf1[1024],buf2[1024];
char *delim=".";
int id;
getwd(buf2);//這段程式碼說明的是對命令提示的路徑獲得
username=getenv("USER");//呼叫getenv函式,來獲得shell命令的提示中的使用者名稱
strcpy(buffer,username);
strcat(buffer,"@");
id=gethostname(buf1,sizeof buf1);//呼叫此函式來獲取shell命令的提示中的主機名
p=strtok(buf1,delim);//對主機進行擷取
strcat(buffer,p);//字串的連線函式
ptr=strrchr(buf2,'/');//字串的從後往前進行擷取的函式,講多得shell命令提示中的路徑
//比較字串,判斷使用者的路徑是在"/","~",還是其他當中
if(strcmp(ptr,"/")==0)
{
ptr="/";
}
else if(strcmp(ptr,"~")==0)
{
ptr="~";
}
else
{
ptr=strtok(ptr,"/");
}
//把獲得的 [使用者名稱@主機名 路徑]連線在一起
strcat(buffer," ");
strcat(buffer,ptr);
return buffer;
}
int main()
{
pid_t pid;
int status;
char *argv[NUM];
char buffer[NUM];
char str[NUM];
int j=-1;
char *string=NULL;
string=getenv("USER");
//當前使用者是root使用者還是普通使用者,通過字串的比較,如果是root,則返回0;
if((strcmp(string,"root"))==0)
{
j=0;
}
while(1){
//通過呼叫上面自定義的getusername()函式,來得到shell命令中的提示
printf("[%s]",getusername(buffer));
//判斷是使用root的提示#,還是其他使用者的$
if(j==0)
{
printf("# ");
}
else
{
printf("$ ");
}
//字串的輸入,要用gets函式或者用fgets函式,因為scanf函式把空格看成字串的結束
gets(str);
//呼叫字串的分割函式,獲得要截取出來的命令和命令引數,例如:ls -a分別放到argv[0],argv[1]中
status=mystrtok(argv,str);
if(status!=0)
{
printf("fail to getargv!\n");
}
//通過fork()函式來建立一個父程序和一個子程序
pid=fork();
if(-1==pid)
{
printf("your fork failed!\n");
}
else if(pid==0)
{
//子程序用來對shell命令程序程序解釋執行的
if(argv[1]!=NULL)
{
execvp(argv[0],argv);
}
else if(argv[1]==NULL)
{
execlp(argv[0],argv[0],NULL,NULL);
}
}
else
{
//父程序用來等待子程序的結束,然後再迴圈輸入shell命令
if(wait(&status)==-1)
{
printf("wait failed!\n");
exit(1);
}
}
}
return 0;
}