【问题标题】:Shell project for executing background processes [closed]用于执行后台进程的 Shell 项目 [关闭]
【发布时间】:2016-07-04 17:26:16
【问题描述】:
int main(void) {
    char in[512];

    pid_t id;
    int status, y, x, i = 1;
    char *f[512];
    char *v;

    while(1)
    {
        printf("shell>");
        fgets(in,512, stdin);
        int size = strlen(in);// calculate dim of in execpt null
        in[size-1] = '\0'; //null at the end because ls\n not executable
        v = strtok(in, " ");
        f[0] = v;
        while (v = strtok(NULL, " ")) {
            f[i] = v;
            i++;
        }
        f[i] = NULL;

        y = strcmp(f[0],"exit");

        if (y == 0)
        break;

        id = fork();

        if (id==0) { //child
            execvp(f[0],f);
            perror("failure");
            exit(1);
        }
        else //parent
        {
            x=strcmp(f[i-1],"&");
            if (x != 0)
            waitpid(id, &status, 0);
        }
    }
}

在这段代码中,我可以执行 shell 命令,但不能执行 command & 部分。如何让execvp在后台执行进程?

【问题讨论】:

  • if(f[0]=="exit")。 C 中的字符串不能使用== 运算符进行比较。需要使用strcmp
  • 请学会使用编辑框左上角的{}格式工具来保持code/data/errorMsgs/etc的格式。祝你好运。
  • 这篇文章不可读。请记住,如果一行以 4 个空格开头,堆栈溢出将其视为代码(并删除这些空格)。要缩进,只需提供额外的空格。
  • 现在我可以执行退出命令,但我想在我的代码中实现在后台执行命令,如“ls&”.. 请问我该怎么办?
  • @A.Mohsen:你应该花几天(或几周)的时间阅读(书籍和源代码)。我们不会做你的功课。一个小外壳至少有一千行源代码,我们不会为您编写它们。你需要学习 & 实验

标签: c shell unix


【解决方案1】:

阅读Advanced Linux Programming。在现有程序(特别是shell)上使用strace(1) 来了解system calls 他们在做什么。查看syscalls(2) 的列表并更准确地阅读其中几个的文档(请参阅intro(2)...)。 研究一些已有的free software shell的源码,如sash & bash

不要忘记系统调用(例如您对fork(2)...的调用)可能会失败。你应该处理失败,至少像:

 id = fork();
 if (id<0) { perror("fork"); exit(EXIT_FAILURE); };

关于结尾&amp;的处理,您正在照顾job control。详细了解process groups

您的程序没有实现 globbingpipelines,并且无法运行带有参数的某些程序(例如,命令 ls a b 应该运行带有三个参数 "ls""a"/bin/ls"b"),每个shell 都应该这样做。见glob(7) & pipe(7)

不要指望我们做你的功课。您可能应该编写一个更大的程序(可能有一千行,几十个函数,几个带有指针的struct,......),并首先考虑它的设计(这是研究现有的地方shell 实现会帮助你)。特别是首先在一张纸(或一些白板)上列出一组要实现的重要功能和数据结构。

我建议首先编写您的 shell 代码,以便能够运行像 ls a b 这样的简单命令,实现 globbing(所以接受 ls *.c)。完成并调试后,考虑实现一些内置函数(特别是 cd)、作业控制和管道。在此之前研究一些现有 shell 的源代码,当然还有实现它所需的主要系统调用。

顺便说一句,使用所有警告和调试信息 (gcc -Wall -Wextra -g) 进行编译,并经常使用调试器 (gdb)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-07
    • 2023-03-04
    • 2015-11-21
    • 1970-01-01
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多