最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

操作系统实验报告_shell

来源:动视网 责编:小OO 时间:2025-10-02 00:58:53
文档

操作系统实验报告_shell

操作系统实习报告日期:实习题目:shell程序完成人姓名:组号:学号"实习内容简要描述本实验要实现一个简单的命令解释器,也就是Linux中的shell程序。实验程序起名为ysh,要求其设计类似于目前流行的shell解释程序,如bash、csh、tcsh,但不需要具备那么复杂的功能。ysh程序应当具有如下一些重要的特征:能够执行外部程序命令,命令可以带参数。能够执行fg、bg、cd、history、exit等内部命令。使用管道和输入输出重定向。支持前后台作业,提供作业控制功能,包括打印作业的清单
推荐度:
导读操作系统实习报告日期:实习题目:shell程序完成人姓名:组号:学号"实习内容简要描述本实验要实现一个简单的命令解释器,也就是Linux中的shell程序。实验程序起名为ysh,要求其设计类似于目前流行的shell解释程序,如bash、csh、tcsh,但不需要具备那么复杂的功能。ysh程序应当具有如下一些重要的特征:能够执行外部程序命令,命令可以带参数。能够执行fg、bg、cd、history、exit等内部命令。使用管道和输入输出重定向。支持前后台作业,提供作业控制功能,包括打印作业的清单
操作系统实习报告          日期: 

实习题目:      shell程序

完成人姓名:组号:学号
"

实习内容简要描述

本实验要实现一个简单的命令解释器,也就是Linux中的shell程序。

实验程序起名为ysh,要求其设计类似于目前流行的shell解释程序,如bash、csh、tcsh,但不需要具备那么复杂的功能。ysh程序应当具有如下一些重要的特征:

能够执行外部程序命令,命令可以带参数。 

  能够执行fg、bg、cd、history、exit等内部命令。

  使用管道和输入输出重定向。

支持前后台作业,提供作业控制功能,包括打印作业的清单,改变

  当前运行作业的前台/后台状态,以及控制作业的挂起、中止和继续

  运行。除此之外,在这个实验中还须做到:

  使用make工具建立工程。

  使用调试器gdb来调试程序。

  提供清晰、详细的设计文档和解决方案。

c

主要代码结构

(附注释)

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include "ysh.h"

#define NO_PIPE -1

#define FD_READ 0

#define FD_WRITE 1

int is_founded(char * cmd)

{

    int k = 0;

    while(envpath[k] != NULL){   strcpy(buf,envpath[k]);

        strcat(buf,cmd);

        if(access(buf,F_OK) == 0){       return 1;

        }  k++;

    }

    return 0;

}

void getenviron(int n,char * s)

{  int i = 0,j = 0,k = 0;

    char c;

    char buff[80];

    char * p;

    while((c=s[i]) != '=') {     buff[i++] = c;

    }  buff[i++] = '\\0';

    if(strcmp(buff,"PATH") == 0) {

        while(s[i] != '\\0'){   if(s[i] == ':') {

                buff[j++] = '/';

                buff[j] = '\\0';

                p = (char *)malloc(strlen(buff) + 1);

                strcpy(p,buff);

                envpath[k++] = p;

                envpath[k] = NULL;

                j = 0;

                i++;

            } else {

                buff[j] = s[i];

                j++;

                i++;

            }

        }

    } else

        fprintf(stderr,"No match");

}

int getline(int fd,char * buf)

{   int i = 0;

    char c;

    while(read(fd,& c,1)) {

        buf[i++] = c;

        if(c == '\\n') {

            buf[i-1] = '\\0';

            return i;

        }

    } return i;

}

void init_environ()

{

    int fd,n;

    char buf[80];

    if((fd = open("ysh_profile",O_RDONLY,660)) == -1) {

        printf("init environ variable error!\\n");

        exit(1);

    }

    while((n = getline(fd,buf)) != 0) {

        getenviron(n,buf);

    }

    envhis.start = 0;

    envhis.end = 0;

    head = end = NULL;

}

int pipel(char * input,int len) 

{   char * argv[10][30];

    char * filename[0];

    int i,j,k,is_bg = 0;

    int li_cmd = 0;

    int fd[10][1],pipe_in = -1;

    int pipe_out = -1,flag = 0;

    pid_t pid;

for(i = 0,j = 0,k = 0;i <= len;i++) {

    if((input[i] == ' ') || (input[i] == '\') || (input[i] == '\\0') ||

(input[i] == '|') || (input[i] == '>') || (input[i] == '\\n')){

if((input[i] == '|') || (input[i] == '>')){

        if(input[i] == '>')    {

            flag =1;

        }

        if(j > 0 )    {

            buf[j++] = '\\0';

            argv[li_cmd][k] = (char *)malloc(sizeof(char) * j);

            strcpy(argv[li_cmd][k],buf);

            k++;

        }

        argv[li_cmd][k] = (char *)0;

         li_cmd++;

         k = 0;

        j = 0;

        }

        if(j == 0)    {

        continue;

        }  else    {

        buf[j++] = '\\0';

        if(flag == 0)    {

            argv[li_cmd][k] = (char *)malloc(sizeof(char) * j);

            strcpy(argv[li_cmd][k],buf);

            k++;

        } else{

            filename[0] = (char *)malloc(sizeof(char) * j);

            strcpy(filename[0],buf);

        }

        }

        j = 0;

    }else {

        if((input[i] == '&') && (input[i] == '\\0')) {

        is_bg = 1;

        continue;

        }

        buf[j++] = input[i];

    }

    }

    argv[li_cmd][k++] = NULL;

for(i = 0;i <= 10;i++) {

    fd[i][FD_READ] = NO_PIPE;

    fd[i][FD_WRITE] = NO_PIPE;

    }

for(i = 0;i < li_cmd;i++) {

    if(pipe(fd[i]) == -1)    {

        printf("Can not open pipe!\\n");

        return 0;

    }

    }

for(i = 0;i < li_cmd;i++) {

    if(is_founded(argv[i][0]) == 0)    {

        printf("Can not found command!\\n");

        break;

    }

    } 

    if(i != 0)    {

    pipe_in = fd[i - 1][FD_READ];

    }   else    {

        pipe_in = NO_PIPE;

    }

    if(i != li_cmd)    {

    pipe_out = fd[i][FD_WRITE];

    }    else

    {    if(flag == 1)    {

        if((pipe_out = open(filename[0],O_WRONLY | O_CREAT | O_TRUNC,

        S_IRUSR | S_IWUSR)) == -1)        {

        printf("Can not open %s\\n",filename[0]);

        return 0;

        }

    }    else    {

         pipe_out = NO_PIPE;

    }

    }

if((pid = fork()) < 0) {

    printf("Fork failed!\\n");

        return 0;

    }

if(pid == 0)    {

    if(pipe_in == NO_PIPE)      {

        close(pipe_in);

    }

    if(pipe_out == NO_PIPE)    {

        close(pipe_out);

    }

    if(pipe_out != NO_PIPE)    {

        dup2(pipe_out,1);

        close(pipe_out);

    }

        if(pipe_in != NO_PIPE)    {

        dup2(pipe_in,0);

        close(pipe_in);

    }

    execv(buf,argv[i]);

}   else   {

    if(is_bg == 0)    {

        waitpid(pid,NULL,0);

    }

    close(pipe_in);

    close(pipe_out);

    }

    return 0;

}

void add_history(char * inputcmd)

{

    envhis.end = (envhis.end + 1) % HISNUM;

    if(envhis.end == envhis.start)   {

    envhis.start = (envhis.start + 1) % HISNUM;

    }

    strcpy(envhis.his_cmd[envhis.end],inputcmd);

}

void history_cmd()

{

    int i,j = 0;

    if(envhis.start == envhis.end)   {

    return;

    }

else if(envhis.start < envhis.end) {

    for(i = envhis.start + 1;i <= envhis.end;i++)    {

        printf("%d\%s\\n",j,envhis.his_cmd[i]);

        j++;

    }

    }    else    {

    for(i = envhis.start + 1;i < HISNUM;i++)    {

        printf("%d\%s\\n",j,envhis.his_cmd[i]);

        j++;

    }

         for(i = 0;i <= envhis.end;i++)    {

        printf("%d\%s\\n",j,envhis.his_cmd[i]);

        j++;

    }

    }

}

void cd_cmd(char * route)

{

    if(route != NULL)    {

    if(chdir(route) < 0)    

        printf("cd;%s Error file or directory!\\n",route);

    }

}

void jobs_cmd()

{

    struct NODE * p;

    int i = 1;

    p = head;

    if(head != NULL)   {

        do

    {

printf("%d %d %s\%s\\n",i,p -> pid,p -> state,p -> cmd);

        i++;

p = p -> link;

    }while(p != NULL);

    }

    else   

        printf("No jobs!\\n");

}

void add_node(char * input_cmd,int node_pid)

{

    struct NODE * p;

    p = (struct NODE *)malloc(sizeof(struct NODE));

p -> pid = node_pid;

strcpy(p -> state,input_cmd);

strcpy(p -> state,"running");

p -> link = NULL;

    if(head == NULL)   {

         head = p;

         end = p;

    }   else    {

end -> link = p;

        end = p;

    }

}

void del_node(int sig,siginfo_t * sip)

{

    struct NODE * q;

    struct NODE * p;

    int id;

    if(sig_z == 1)    {

        sig_z = 0;

    goto out;

    }    

id = sip -> si_pid;

    p = q = head;

    if(head == NULL)  

     goto out;

while(p -> pid != id && p -> link != NULL) {

p = p -> link;

    }

if(p -> pid != id)

    goto out;

    if(p == head)    

        head = head -> link;

    else   {

    while(q -> link != p)    {

q = q -> link;

    }

    if(p == end)    {

        end = q;

q -> link = NULL;

    }    else    {

q -> link = p -> link;

    }

    }    

    free(p);

    out:return;

}

void setflag(){

    sig_flag = 1;

}

void ctrl_z()

{

    struct NODE * p;

    int i = 1;

    if(pid1 == 0)    {

        goto out;

    }    

    if(head != NULL)   {

        p = head;

        while((p -> pid != pid1) && (p -> link != NULL))    {

p = p -> link;

    }

    if(p -> pid == pid1)    {

strcpy(p -> state,"stopped");

    }    else

    {

        add_node(input,pid1);

strcpy(end -> state,"stopped");

    }

    }

    else

    {

    add_node(input,pid1);

strcpy(end -> state,"stopped");

    }

    sig_z = 1;

    kill(pid1,SIGSTOP);

for(p = head;p -> pid != pid1;p = p -> link)

    {

    i++;

    }

printf("[%d]\%s\%s\\n",i,end -> state,end -> cmd);

    pid1 = 0;

out:return;

}

void bg_cmd(int job_num)

{

    struct NODE * p;

    int i = 0;

    p = head;

for(i = 1;i < job_num;i++)

    {

p = p -> link;

    }  

kill(p -> pid,SIGCONT);

strcpy(p -> state,"running");

}

void fg_cmd(int job_num)

{

    struct NODE * p;

    int i = 0;

    p = head;

for(i = 1;i < job_num;i++)

    {

p = p -> link;

    }

strcpy(p -> state,"running");

strcpy(input,p -> cmd);

pid1 = p -> pid;

    signal(SIGTSTP,ctrl_z);

kill(p -> pid,SIGCONT);

waitpid(p -> pid,NULL,0);

}

int main()

{

    init_environ();

    while(1)

    {

    char c;

        char * arg[20];

        int i = 0,j = 0,k = 0;

        int is_pr = 0,is_bg = 0;

        int input_len = 0,path;

        int pid = 0,status = 0;

        struct sigaction action;

    action.sa_sigaction = del_node;

    sigfillset(& action.sa_mask);

    action.sa_flags = SA_SIGINFO;

    sigaction(SIGCHLD,& action,NULL);

    signal(SIGTSTP,ctrl_z);

        path = get_current_dir_name();

    printf("ysh@%s ",path);

    while(((c = getchar()) == ' ') || (c == '\') || (c == EOF))

    {

        ;

    }

    if(c == '\\n')

    {

        continue;

    }

    while(c != '\\n')

    {

        buf[input_len++] = c;

        c = getchar();

    }

    buf[input_len] = '\\0';

        input = (char *)malloc(sizeof(char) * (input_len + 1));

    strcpy(input,buf);

        for(i = 0,j = 0,k = 0;i <= input_len;i++)

    {

if((input[i] == '<') || (input[i] == '>') || (input[i] == '|'))

        {

        if(input[i] == '|')

        {

            pipel(input,input_len);

            add_history(input);

            free(input);

        }

        else

        {

            redirect(input,input_len);

            add_history(input);

            free(input);

        }

        is_pr = 1;

        break;

        }

    }

    if(is_pr == 1)

    {

        continue;

    }

for(i = 0,j = 0,k = 0;i <= input_len;i++)

    {

        if((input[i] == ' ') || (input[i] == '\\0'))

        {

            if(j == 0)

            {

            continue;

            }

            else

            {

            buf[j++] = '\\0';

            arg[k] = (char *)malloc(sizeof(char) * j);

            strcpy(arg[k++],buf);

            j = 0;

            }

        }

          else

        {

            if((input[i] == '&') && (input[i + 1] == '\\0'))

            {

            is_bg = 1;

            continue;

            }

            buf[j++] = input[i];

        }

        }

        if(strcmp(arg[0],"exit") == 0)

    {

        add_history(input);

        printf("Bye bye!\\n");

        free(input);

        break;

    }

        if(strcmp(arg[0],"history") == 0)

    {

        add_history(input);

        history_cmd();

        free(input);

        continue;

    }

    if(strcmp(arg[0],"cd") == 0)

    {

        add_history(input);

for(i = 3,j = 0;i <= input_len;i++)

        {

        buf[j++] = input[i];

        }

        buf[j] = '\\0';

        arg[1] = (char *)malloc(sizeof(char) * j);

        strcpy(arg[1],buf);

        cd_cmd(arg[1]);

        free(input);

        continue;

    }

    if(strcmp(arg[0],"jobs") == 0)

    {

        add_history(input);

        jobs_cmd();

        free(input);

        continue;

    }

    if(strcmp(arg[0],"bg") == 0)

    {

        add_history(input);

for(i = 0;i <= input_len;i++)

        {

        if(input[i] == '%')

        {

            break;

        }

        }    

        i++;

for(;i <= input_len;i++)

        {

        buf[j++] = input[i];

        }

        buf[j] = '\\0';

        arg[1] = (char *)malloc(sizeof(char) * j);

        strcpy(arg[1],buf);

        bg_cmd(atoi(arg[1]));

        free(input);

        continue;

    }

    if(strcmp(arg[0],"fg") == 0)

    {

        add_history(input);

for(i = 0;i <= input_len;i++) {

        if(input[i] == '%'){

            break;

        }

        }

        i++;

for(;i <= input_len;i++)

        {

        buf[j++] = input[i];

        }

        buf[j] = '\\0';

        arg[1] = (char *)malloc(sizeof(char) * j);

        strcpy(arg[1],buf);

        fg_cmd(atoi(arg[1]));

        free(input);

        continue;

    }

    if(is_pr == 0)

    {

        arg[k] = (char *)malloc(sizeof(char));

        arg[k] = NULL;

        if(is_founded(arg[0]) == 0)

        {

        printf("This command is not founed!\\n");

        for(i = 0;i <= k;i++)

        {

            free(arg[i]);

        }

        continue;

        }

    }

    add_history(input);

    if((pid = fork()) == 0)

    {

        if(is_bg == 1)

        {

        while(sig_flag == 0)

        {

            signal(SIGUSR1,setflag);

        }

        sig_flag = 0;

        }

    }else{

        pid1 = pid;

        if(is_bg == 1) {

        add_node(input,pid1);

        kill(pid,SIGUSR1);

        pid1 = 0;

        } if(is_bg == 0){

        waitpid(pid,& status,0);

        }

    }if(is_bg == 1)    {

        sleep(1);

    }for(i = 0;i < k;i++)    {

        free(arg[i]);

        free(input);   

    }

    }

   return 0;

}

"

结果分析(或错误原因分析)

通过本次实验使我们熟悉使用Linux下的软件开发工具,例如gcc、gdb和make。

 在编写系统应用程序时熟练使用man帮助手册。

学习使用POSIX/UNIX系统调用、对进程进行管理和完成进程之间的通信,例如使用信号和管道进行进程间通信。

 理解并发程序中的同步问题。

 锻炼在团队成员之间的交流与合作能力

注释:如果上述表格空间不够,可以另附表格进行说明

文档

操作系统实验报告_shell

操作系统实习报告日期:实习题目:shell程序完成人姓名:组号:学号"实习内容简要描述本实验要实现一个简单的命令解释器,也就是Linux中的shell程序。实验程序起名为ysh,要求其设计类似于目前流行的shell解释程序,如bash、csh、tcsh,但不需要具备那么复杂的功能。ysh程序应当具有如下一些重要的特征:能够执行外部程序命令,命令可以带参数。能够执行fg、bg、cd、history、exit等内部命令。使用管道和输入输出重定向。支持前后台作业,提供作业控制功能,包括打印作业的清单
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top