#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define MAX_HOST_LEN 32 /* 主机名最大长度 */
#define MAX_PATH_LEN 256 /* 路径的最大长度 */
#define MAX_COMMAND_LEN 256 /*命令的最大长度*/
struct job {
char * precmd; /* 转换前的命令*/
char ** formatcmd; /* 转换后的命令*/
};
struct promptinfo {
char * username; /* 当前用户名*/
char * hostname; /* 主机名*/
uid_t userid; /* 当前用户id */
char * pwdname; /* 当前路径名 */
char promptchar; /* '#' 为管理员, '$' 普通用户 */
char * home; /* 主路径 */
}prinfo;
int getprinfo() {
prinfo.userid = getuid();/*得到用户ID*/
/* 得到当前用户名 */
if ( (prinfo.username = getenv("USER")) == NULL) {
perror("getlogin error");
return -1;
}
/* 获得主机名*/
if ( (prinfo.hostname = malloc(MAX_HOST_LEN) ) == NULL) {
perror("malloc hostname error");
return -2;
}
if ( gethostname(prinfo.hostname, MAX_HOST_LEN) != 0) {
perror("get hostname error");
return -2;
}
/* 获得当前路径名*/
if ( (prinfo.pwdname = malloc(MAX_PATH_LEN) ) == NULL) {
perror("malloc pwdname error");
return -3;
}
if ( (prinfo.pwdname = getcwd(prinfo.pwdname, MAX_PATH_LEN)) == NULL) {
perror("get current path error");
return -3;
}
/* 获得命令行提示符 */
if (prinfo.userid < 0) {
printf("getuid error.");
return -4;
}
if (prinfo.userid == 0) {
prinfo.promptchar = '#';
} else {
prinfo.promptchar = '$';
}
/* 获得主路径名*/
if ( (prinfo.home = getenv("HOME")) == NULL) {
perror("get home path error");
return -5;
}
return 0;
}
void prompt() {
printf("\033[00;32m%s\033[00;35m@\033[00;36m%s\033[00;33m:\033[00;34m%s\033[00;31m%c\033[00m ",
prinfo.username,
prinfo.hostname,
prinfo.pwdname,
prinfo.promptchar);
}
char ** parseCommand(char * precommand, char ** formatcmd) { /*把命令转换成字符串数组 */
char c;
int count = 0,i = 0,j = 0;
if ( (formatcmd = malloc(sizeof(char*))) == NULL) {
perror("malloc to formatcmd error");
return NULL;
}
if ( (formatcmd[0] = malloc( (strlen(precommand) + 1) * (sizeof(char) ) ) ) == NULL) {
perror("malloc to formatcmd[0] error");
return NULL;
}
while ((c = precommand[i]) == 32) {
i++;
} /* 忽略命令前面的空格*/
while (i < strlen(precommand)) {
c = precommand[i];
if (c == 32) {
while ((c = precommand[i]) == 32) {
i++;
}
formatcmd[count][j] = '\0';
count++;
formatcmd = realloc(formatcmd, count);
if ( (formatcmd[count] = malloc(sizeof(char) * (strlen(precommand) - i + 1) )) == NULL) {
fprintf(stderr,
"malloc formatcmd[%d] error %d: %s",
count,
errno,
strerror(errno));
return NULL;
}
j = 0;
} else {
formatcmd[count][j] = c;
j++;
i++;
}
}
formatcmd[count][j] = '\0';
count++;
formatcmd = realloc(formatcmd, count);
formatcmd[count] = NULL;
return formatcmd;
}
/* main fuction here !!! */
int main(int argc, char * argv[]) {
struct job joba;
char cmdbuf[MAX_COMMAND_LEN];
pid_t child;
int status;
if (getprinfo() < 0) {
printf("getprinfo error\n");
exit(-1);
}
prompt();
while ((fgets(cmdbuf, MAX_COMMAND_LEN, stdin)) != NULL) {
cmdbuf[strlen(cmdbuf) -1] = '\0';/* 以‘\0'结束*/
if (strcmp(cmdbuf, "exit") ==0) {
exit(0);
}
joba.precmd = cmdbuf;
if ((joba.formatcmd = parseCommand(joba.precmd, joba.formatcmd)) != NULL) {
/*如果只输入cd不带参数 直接进入主目录 */
if (strcmp(joba.formatcmd[0], "cd") == 0) {
if (joba.formatcmd[1] == NULL){
joba.formatcmd[1] = prinfo.home;
}
if (chdir(joba.formatcmd[1]) < 0) {
perror("cd");
}
getprinfo();
}
else {
if ((child = fork()) < 0) { /* 创建子进程失败 */
fprintf(stderr,
"fork error %d: %s\n",
errno,
strerror(errno));
}
/* 进入子进程 */
if(child == 0) {
if (execvp(joba.formatcmd[0],
joba.formatcmd) < 0){
perror("exec error");
}
exit(0);
}
/* 等待子进程结束 */
if ((waitpid(child, &status, 0)) < 0) {
perror("waitpid error");
}
}
}
prompt();
}
return 0;
}
用c语言实现的shell解释器
需积分: 18 133 浏览量
2010-03-24
15:28:15
上传
评论 1
收藏 2KB RAR 举报
liyongli123456
- 粉丝: 1
- 资源: 2
最新资源
- 人工智能ai相关教学课程快
- Suno的冲击-AI音乐来了-学习备用.pdf
- KIMI大模型浏览器插件
- b61fa64a08a02de0e0d49d53bb84c444.amr
- 分布式系统中Java后端开发技术及其应用实践.pdf
- 5ffd9193f6aec31bbf16030a46680dc7.avi
- DA14531-蓝牙传感器连接传输数据固件
- 极限存在准则与两个重要极限
- logisim实验MIPS运算器(ALU)设计(内含4位先行进位74182、四位快速加法器、32位快速加法器)-Educoder_logisim里面连线,实现4位先行进位74182和4位快速加法器-C
- 高等数学第一章第二节数列的极限
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈