a。帶一個輸入重定向的命令,如wc-ca&wc-c

亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

編程實踐:實現自己的myshell

系統 2314 0

這個簡單的Shell,其功能有:解釋執行命令,支持輸入輸出重定向,支持管道,后臺運行程序。
??? 1、運行本程序后,它支持以下命令格式
??? 單個命令,如:ls。
??? 帶l到多個參數的命令,如ls -l /tmp。
??? 帶一個輸出重定向的命令,如ls -l / > a。
??? 帶一個輸入重定向的命令,如wc -c < a。
??? 帶一個管道的命令,如ls -l / | wc -c
??? 后臺運行符&可回在以上各個命令的最后面。
??? 如:ls &
????????? ls -l /tmp &
????????? ls -l / >a &
????????? wc -c < a &
????????? ls -l / | wc -c &
??? 輸入exit或logout退出程序。
??? 2、錯誤處理
??? 輸入錯誤的命令格式報錯。
??? 輸入不存在的命令報錯。
??? 3、關鍵函數的功能及說明
??? (1)void printf_prompt()
??? 函數說明:該函數只是簡單地打印myshell的提示符,即"myshell&&"。
??? (2)void get_input(char *buf)
??? 函數說明:獲得一條用戶輸入的待執行的命令,參數buf用于存放輸入的命令。如果輸入的命令過長(大于256個字符),則終止程序。輸入的命令以換行符“\n”作為結束標志。
??? (3)void explain_input(char *buf,int *argcount,char arglist[100][256])
??? 函數說明:解析buf中存放的命令,把每個選項存放在arglist中。如輸入命令“ls -l /tmp”,則arglist[0],arglist[1],arglist[2]指向的字符串分別為“ls”,“-l”,“/tmp”。
??? (4)do_cmd(int argcount,char arglist[100][256])
??? 函數說明:執行arglist中存放的命令,argcount為待執行命令的參數個數。
??? (5)int find_command(char *command)
??? 函數說明:功能是分別在當前目錄下,/bin,/usr/bin目錄下查找命令的可執行程序。
??? 5、程序實現源代碼如下:
??? 例7-12
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <dirent.h>

#define normal???????? 0 /*一般的命令*/
#define out_redirect?? 1 /*輸出重定向*/
#define in_redirect??? 2 /*輸入重定向*/
#define have_pipe????? 3 /*命令中有管道*/

void print_prompt();?????????????????????????? /*打印提示符*/
void get_input(char *);??????????????????????? /*得到輸入的命令*/
void explain_input(char *,int *,char a[100][256]);?? /*對輸入命令進行解析*/
void do_cmd(int ,char a[100][256]);????????????????? /*執行命令*/
int find_command(char *);????????????????????? /*查找命令中的可執行程序*/

int main(int argc,char **argv)
{
int i;
int argcount = 0;
char arglist[100][256];
char **arg = NULL;
char *buf = NULL;

buf = (char *)malloc(256);
if (buf == NULL){
??? perror("malloc failed");
??? exit(-1);
}

while(1){
??? /*將buf所指向的空間清零*/
??? memset(buf,0,256);
??? print_prompt();
??? get_input(buf);
??? /*若輸入的命令為exit或logout則退出本程序*/
??? if (strcmp(buf,"exit\n") == 0 || strcmp(buf,"logout\n") == 0)
????? break;
??? for (i=0;i<100;i++){
????? arglist[i][0] = '\0';
??? }
??? argcount = 0;
??? explain_input(buf,&argcount,arglist);
??? do_cmd(argcount,arglist);
}

if (buf != NULL){
??? free(buf);
??? buf = NULL;
}
exit(0);
}

void print_prompt()
{
printf("myshell$$");
}

/*獲取用戶輸入*/
void get_input(char *buf)
{
int len = 0;
int ch;

ch = getchar();
while (len <256 && ch != '\n'){
??? buf[len++] = ch;
??? ch = getchar();
}

if (len ==256){
??? printf("commond is too long \n");
??? exit(-1); /*輸入的命令過長則退出程序*/
}
buf[len] = '\n';
len++;
buf[len] = '\0';
}

/*解析buf中的命令,將結果存入arglist中,命令以回車符號\n結束*/
/*如輸入命令為“ls -l /tmp”,則arglist[0],arglist[1],arglist[2]分別為ls,-l和/tmp*/

void explain_input(char *buf,int *argcount,char arglist[100][256])
{
char *p = buf;
char *q = buf;
int number = 0;

while(1){
??? if (p[0] == '\n')
????? break;
??? if (p[0] == ' ')
????? p++;
??? else {
????? q = p;
????? number = 0;
????? while ((q[0] != ' ') && (q[0] != '\n')){
??? number++;
??? q++;
????? }
????? strncpy(arglist[*argcount],p,number+1);
????? arglist[*argcount][number] = '\0';
????? *argcount = *argcount + 1;
????? p = q;
??? }
}
}

void do_cmd (int argcount,char arglist[100][256])
{
int flag = 0;
int how = 0;?????????? /*用于指示命令中是否含有>,<,|*/
int background = 0;??? /*標識命令中是否有后臺運行標識符*/
int status;
int i;
int fd;
char *arg[argcount+1];
char *argnext[argcount+1];
char *file;
pid_t pid;

/*將命令取出*/
for (i=0;i<argcount;i++){
??? arg[i] = (char *)arglist[i];
}
arg[argcount] = NULL;

/*查看命令行是否有后臺運行符*/
for (i=0;i<argcount;i++){
??? if (strncmp(arg[i],"&",1) == 0){
????? if (i == argcount - 1){
??? background = 1;
??? arg[argcount-1] = NULL;
??? break;
????? }
????? else {
??? printf("wrong command\n");
??? return;
????? }
??? }
}
for (i=0;arg[i] != NULL;i++){
??? if (strcmp(arg[i],">") == 0){
????? flag++;
????? how = out_redirect;
????? if (arg[i+1] == NULL)
??? flag++;
??? }
??? if (strcmp(arg[i],"<") == 0){
????? flag++;
????? how = in_redirect;
????? if (i == 0)
??? flag++;
??? }
??? if (strcmp(arg[i],"|") == 0){
????? flag++;
????? how = have_pipe;
????? if (arg[i+1] == NULL)
??? flag++;
????? if (i == 0)
??? flag++;
??? }
}

/*flag大于1,說明命令中含有多個>,<,|符號,本程序是不支持這樣的命令的,
??? 或者命令格式不對,如“ls -l /tmp >”*/
if (flag > 1){
??? printf("wrong command\n");
??? return;
}
if (how == out_redirect){/*命令只含有一個輸出重定向符號>*/
??? for (i=0;arg[i] != NULL;i++){
????? if (strcmp(arg[i],">") == 0){
??? file = arg[i+1];
??? arg[i] = NULL;
????? }
??? }
}

if (how == in_redirect){/*命令只含有一個輸入重定向符號<*/
??? for (i=0;arg[i] != NULL;i++){
????? if (strcmp(arg[i],"<") == 0){
??? file = arg[i+1];
??? arg[i] = NULL;
????? }
??? }
}

if (how == have_pipe){/*命令只含有一個管道符號|*/
??? /*把管道符號后面的部分存入argnext中,管道后面的部分是一個可執行的Shell命令*/
??? for (i=0;arg[i] != NULL;i++){
????? if (strcmp(arg[i],"|") == 0){
??????? arg[i] = NULL;
??????? int j;
??????? for (j=i+1;arg[j] != NULL;j++){
??? argnext[j-i-1] =arg[j];
??????? }
??? argnext[j-i-1] = arg[j];
??? break;
????? }
??? }
}

if ((pid = fork()) < 0) {
??? printf("fork error\n");
??? return;
}

switch(how) {
??? case 0:
????? /*pid為0說明是子進程,在子進程中執行輸入的命令*/
????? /*輸入的命令中不含>,<和|*/
????? if (pid == 0){
??? if (!(find_command(arg[0]))){
??? printf("%s:command not found\n",arg[0]);
??? exit(0);
??? }
??? execvp(arg[0],arg);
??? exit(0);
????? }
????? break;
??? case 1:
????? if (pid == 0){
??? if (!(find_command(arg[0]))){
??? printf("%s:command not found\n",arg[0]);
??? exit(0);
??? }
??? fd = open(file,O_RDWR|O_CREAT|O_TRUNC,0644);
??? dup2(fd,1);
??? execvp(arg[0],arg);
??? exit(0);
????? }
????? break;
??? case 2:
????? /*輸入的命令中含有重定向符<*/
????? if (pid == 0){
??? if (!(find_command(arg[0]))){
??? printf("%s:command not found\n",arg[0]);
??? exit(0);
??? }
??? fd = open(file,O_RDONLY);
??? dup2(fd,0);
??? execvp(arg[0],arg);
??? exit(0);
????? }
????? break;
??? case 3:
????? /*輸入的命令中含有管道*/
????? if (pid == 0){
??? int pid2;
??? int status2;
??? int fd2;

??? if ((pid2 = fork()) < 0){
??? printf("fork2 error\n");
??? return;
??? }
??? else if (pid2 == 0){
??? if (!(find_command(arg[0]))){
??????? printf("%s:command not found\n",arg[0]);
??????? exit(0);
??? }
??? fd2 = open("/tmp/youdonotknowfile",O_WRONLY|O_CREAT|O_TRUNC,0644);
??? dup2(fd2,1);
??? execvp(arg[0],arg);
??? exit(0);
??? }
??? if (waitpid(pid2,&status2,0) == -1)
??? printf("wait for child process error\n");

??? if (!(find_command(argnext[0]))){
??? printf("%s:command not found\n",argnext[0]);
??? exit(0);
??? }
??? fd2 = open("/tmp/youdonotknowfile",O_RDONLY);
??? dup2(fd2,0);
??? execvp(argnext[0],argnext);

??? if (remove("/tmp/youdonotknowfile"))
??? printf("remove error\n");
??? exit(0);
????? }
????? break;
??? default:
????? break;
}

/*若命令中有&,表示后臺執行,父進程直接返回,不等待子進程結束*/
if (background == 1){
??? printf("[process id %d]\n",pid);
??? return;
}

/*父進程等待子進程結束*/
if (waitpid(pid,&status,0) == -1)
??? printf("wait for child process error\n");

}

int find_command(char *command)
{
DIR *dp;
struct dirent *dirp;
char *path[] = {"./","/bin","/usr/bin",NULL};

/*使當前目錄下的程序可以運行,如命令"./fork"可以被正確解釋和執行*/
if (strncmp(command,"./",2) == 0)
??? command = command + 2;

/*分別在當前目錄、/bin和/usr/bin目錄查找要執行的程序*/
int i = 0;
while (path[i] != NULL){
??? if ((dp = opendir(path[i])) == NULL)
????? printf("can not open /bin \n");
??? while((dirp = readdir(dp))!= NULL){
????? if (strcmp(dirp->d_name,command) == 0){
??? closedir(dp);
??? return 1;
????? }
??? }
??? closedir(dp);
??? i++;
}
return 0;
}
??? 程序的運行結果如下:
myshell$$ls -l
總用量 279884
-rw-r--r-- 1 monalisa monalisa???? 1389 2009-06-08 22:35 1.txt
-rwxr-xr-x 1 monalisa monalisa???? 9187 2009-05-03 22:37 2-10
-rw-r--r-- 1 monalisa monalisa????? 186 2009-05-03 17:49 2-10.c
-rw-r--r-- 1 monalisa monalisa????? 181 2009-05-03 17:43 2-10.c~

編程實踐:實現自己的myshell


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产亚洲精品自在久久不卡 | 国产成人啪午夜精品网站 | 四虎成人精品在永久免费 | 欧美成人xx免费视频 | 国产高清自拍视频 | 一级呦女专区毛片 | 麻豆精品永久免费视频 | 日本久久久久亚洲中字幕 | 毛片女人毛片一级毛片毛片 | 四虎网站在线 | 日韩在线欧美在线 | 精品午夜寂寞影院在线观看 | 日本一级一片免费 | 国产手机在线精品 | 亚洲视频在线视频 | 伊人久久在线视频 | 2046影院视频大全在线观看 | 伊人影院视频 | 免费a大片| 亚洲国产一区在线二区三区 | 日本色色网 | 国产亚洲精品成人久久网站 | 草草视频免费观看 | 亚欧中文字幕 | 色综合天天综合网看在线影院 | 深夜在线影院 | 国产成人麻豆精品video | 日本一级成人毛片免费观看 | 中文字幕伦理聚合第一页 | 中文字幕在线观看亚洲日韩 | 猫咪www免费人成在线观看网址 | 九九九国产在线 | 青草国产精品久久久久久 | 国产成人啪午夜精品网站 | 性生活视频网 | 久久精品夜色国产 | 久久亚洲精品中文字幕三区 | 4虎最新地址| 九九365资源稳定资源站 | 亚洲国产精品不卡毛片a在线 | 亚洲伊人久久大香线蕉结合 |