【问题标题】:Writing C Shell with combination pipes and redirection使用组合管道和重定向编写 C Shell
【发布时间】:2013-04-03 03:42:20
【问题描述】:

我正在尝试在 C 中实现一个迷你 shell,它将接受 、>>、|、& 的任何组合。我把它放在它读取命令和执行文件重定向等的地方,但是,我似乎无法通过谷歌找到一个很好的教程,说明如何对其进行编程以接受上述命令的任何组合。到目前为止我的代码如下(我删除了我尝试过的组合内容,因为我不知道该怎么做,而且一团糟)(一些非标准函数来自我的库正在使用。):

int main(int argc, char **argv)
{
int i,j,frv,status,x,fd1;
IS is;
is = new_inputstruct(NULL);

/* read each line of input */
while (get_line(is) >= 0)
{
    if (is->NF != 0)
    {

        /*fork off a new process to execute the command specified */
        frv = fork();
        /* if this is the child process, execute the desired command */
        if (frv == 0)
        {
            if (strcmp(is->fields[is->NF-1],"&") == 0) is->fields[is->NF-1] = NULL;
            while (is->fields[frv] != NULL)
            {
                /* if we see <, make the next file standard input */
                if (strcmp(is->fields[frv],"<") == 0)
                {
                    is->fields[frv] = NULL;
                    fd1 = open(is->fields[frv+1], O_RDONLY);
                    dup2(fd1, 0);
                    close(fd1);

                }
                /* if we see >, make the next file standard output and create/truncate it if needed */
                else if (strcmp(is->fields[frv],">") == 0)
                {
                    is->fields[frv] = NULL;
                    fd1 = open(is->fields[frv+1],O_TRUNC | O_WRONLY | O_CREAT, 0666);
                    dup2(fd1, 1);
                    close(fd1);

                }
                /* if we see >>, make the next file standard output and create/append it if needed */
                else if (strcmp(is->fields[frv],">>") == 0)
                {
                    is->fields[frv] = NULL;
                    fd1 = open(is->fields[frv+1], O_WRONLY | O_APPEND | O_CREAT, 0666);
                    dup2(fd1, 1);
                    close(fd1);

                }
                frv++;
            }
            /* execute the command */
            status = execvp(is->fields[0], is->fields);
            if (status == -1)
            {
                perror(is->fields[0]);
                exit(1);
            }
        }
        /* if this is parent process, check if need to wait or not */
        else
        {
            if (strcmp(is->fields[is->NF-1],"&") != 0) while(wait(&status) != frv);
        }
        /* clean up the values */
        for(j = 0; j < is->NF; j++) is->fields[j] = NULL;
    }
}
return 0;
}

【问题讨论】:

  • 我以前学过的书是:UNIX Systems Programming: Communication, Concurrency and Threads,作者 Kay A. Robbins。
  • 处理| 的代码在哪里?它没有显示。有很多相关的问题(参见页面的 RHS)——你确定答案不在其中吗?
  • @JonathanLeffler 我还没有做管道。这是其中一件事我不知道当重定向和管道结合使用时如何处理..
  • |&amp; 符号标志着命令的结束。当有管道时,您有另一个命令要处理。当有 & 符号时,您只需在后台运行命令而无需等待。使用管道,您将 LHS 命令的标准输出设置为管道的写入端,并将 RHS 命令的标准输入设置为管道的读取端。然后您从左到右处理其他 I/O 重定向,一次一个。 [...继续...]
  • [...continuation...] 如果这样会关闭原始(管道)标准输出,那就这样吧。所以:ls -l 2&gt;&amp;1 &gt;/dev/null | wc -lls 的标准输出发送到管道,然后更改标准错误,使其也进入管道;然后它将标准输出发送到/dev/null,所以实际上wc -l 命令只计算ls -l 命令产生的错误输出的行数。

标签: c shell system systems-programming


【解决方案1】:

你必须先标记你的输入命令。

一个标记是一个或多个确实有意义的符号的集合。

例如&amp;|&gt;&gt;&gt;&lt; 是令牌。

看看here,了解如何开始编写词法分析器(它并不复杂)。

也许编译器构建的一些基础知识也会有所帮助。

【讨论】:

  • 我想你会发现标记化是由new_inputstruct() 函数完成的,类型为IS(大概是'input struct' 的缩写)。
  • @JonathanLeffler 是对的。 IS 确实将每行输入中的每个标记放入一个数组中。每行的tokens(fields)个数是is->NF,字段在is->fields
猜你喜欢
  • 2018-03-24
  • 2023-03-04
  • 1970-01-01
  • 2016-06-03
  • 1970-01-01
  • 1970-01-01
  • 2016-07-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多