shell编程和写一个shell不是一回事,但如果写一次shell,再学习shell编程就简单了。
以下是本人编写的简易的交互式Shell。
需要用到的函数有:getpwuid,gethostname,getcwd
#include<stdio.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/types.h>
#include<stdlib.h>
#include<pwd.h>
#include<string.h>
void GetLoginName() //获取登录名
{
struct passwd*pwd;
pwd=getpwuid(getuid());
printf("[%s@",pwd->pw_name);
}
void GetHostName()//获取主机名
{
char name[100]={0};
gethostname(name,sizeof(name)-1);
printf("%s",name);
}
void GetDir()//获取当前工作路径
{
char pwd[100]={0};
getcwd(pwd,sizeof(pwd)-1);
int len=strlen(pwd);
char*p=pwd+len;
while(*p!='/'&&len--)
{
p--;
}
p++;
printf(" %s]#",p);
}
int main()
{
while(1)
{
GetLoginName();
GetHostName();
GetDir();
fflush(stdout);
//sleep(5);
char cmd[128];
ssize_t _s=read(0,cmd,sizeof(cmd)-1);
cmd[_s-1]='\0';
if(_s>0)
{
cmd[_s]='\0';
}
else
{
perror("read");
return 1;
}
char *_argv[32];
char *start = cmd;
_argv[0]=cmd;
int i = 1;
while(*start)
{
if(isspace(*start))
{
*start = '\0';
start++;
_argv[i]=start;
i++;
continue;
}
start++;
}
pid_t id=fork();
if(id<0)
{
perror("fork");
}
else if(id==0)
{
execvp(_argv[0],_argv);
perror("error");
}
else
{
int status = 0;
pid_t ret = waitpid(id,&status,0);
if(ret>0&&WIFEXITED(status))
{
// sleep(1);
//exit(1);
}
else
{
perror("waitpid");
}
}
}
}
用户在命令行输入命令后,一般情况下shell会fork并exec该命令,但是shell的内建命令例外,执行内建命令相当于调用shell进程中的一个函数,并不创建新的进程。以前学过的cd、umask、exit等都是内建命令,凡是用which命令查不到程序文件所在位置的命令都是内建命令。