c - 为家庭作业制作 shell

标签 c shell stdout dup2

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>

void exec(char **args){
    pid_t  pid;
    int status;
    if ((pid = fork()) < 0) {    
    printf("*** ERROR: forking child process failed\n");
    exit(1);
}

else if (pid == 0) {      

    if(execvp(args[0],args)<0)//{
        //printf("argv[0]=%s argv[1]=%s",args[0],args[1]);
        printf("**error in exec\n");
    }

    else {                                  
        while (wait(&status) != pid);
    }
}

void exec2(char **args, char *file){
    printf("file =%s\n",file);
    int fd;
    pid_t pid;
    int status;
    if ((pid = fork()) < 0) {    
printf("*** ERROR: forking child process failed\n");
        exit(1);
    }

    else if (pid == 0) {   
    fd = open(file, O_RDWR | O_CREAT, (mode_t)0600);
    close(1);
    dup2(fd, 1);
    if(execvp(args[0],args)<0){
        printf("**error in exec");
    }

else {  
        printf("\nhere\n");
        close(fd);                                
        while (wait(&status) != pid){
            fflush(stdout) ;
        }
    }
}
    close (fd);
}


void main(){
    char *command;
    char inp[512];
    char *filepath;
    size_t size=0;
    char *substr;
    char *args[512];
    command = (char *) malloc(sizeof(char *) * 512);
    int flag=0;
    int redirect=0;
    int i=0;
    while (1){
        printf("$ ");
        command = fgets(inp, 512/*sizeof(char *)*/, stdin);

        command[strlen(command)-1]='\0';

        if (strchr(command,'>')){
            redirect=1;
            strtok_r(command,">",&filepath);
        }

        size_t siz=4;
        //printf("command=%s\n",command);
        int i=0;
        while(1){
            //printf("i=%d\n",i);
            char *tok = strtok_r(command," ",&substr);
            if (tok==NULL){
                break;
            }
        args[i++] = tok;
/*          printf("tok=%s\n",tok);
            printf("len tok = %d\n",(int)strlen(tok));
            printf("command=%s\n",command);
            printf("substr=%s\n",substr);     
   */           command = substr;
        }

        //printf("args[0]=%s",args[0]);
        if (!strncasecmp(args[0],"exit",siz) || !strncasecmp(args[0],"quit",siz))
        {
            printf("\nBye\n");
            exit(0);
        }

        else if(strcmp(args[0],"cd")==0){
            chdir(args[1]);
            //printf("chdir")   ;
            //system("pwd");
    } 

    else if (redirect==1){
        exec2(args,filepath);
    }

    else exec(args);
}
}

好的,这是我的 shell 代码。当我运行它时,我输入 ls 并给出正确的输出。然后我放 ls -l 然后再放 ls 然后它给出 ls:无法访问:没有那个文件或目录 此外,当我使用 cd 时,ls 不提供输出并且 pwd 说“忽略未使用的参数” 猫也不起作用。 尽管 mkdir、ps 和 ls -l 有效。

最佳答案

不要关闭stdout!

这样做,在 fork 之后和 exec 之前:

if (child) {
  int fd = open(file, O_RDWR | O_CREAT, (mode_t)0600);
  close(1);
  dup2(fd, 1);
  if(execvp(args[0],args)<0){
    printf("**error in exec");
  }
} 

关于c - 为家庭作业制作 shell ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13345340/

相关文章:

linux - 我想读取 "PUB"字符串,如果找到则读取下一个 50 个字符并追加到 excel 文件中

windows - 批处理循环错误 - 仅复制 1 个文件

Haskell 读取前 n 行

与子进程 stdout/stdin 通信

c - C编程中如何扫描两个或多个包含空格的字符串?

c - 字符串复制函数: simple issue

c - 假设指向同一变量的两个指针是非法的/UB,为什么 C 编译器不能优化更改 const 指针的值?

c++ - fopen : is it good idea to leave open, 还是使用缓冲区?

bash - 在 shell 脚本变量中查找子字符串

python - 如何在 Python 中获取标准输出的硬标签