6

我正在尝试编写外壳程序。但是我的 shell 不执行命令 - ls -l | 较少的。我正在使用 execvp。代码如下。

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(){
    int pid, status, num, len;
    char str[1000], cwd[100];
    char* word[100];

    getcwd(cwd, sizeof(cwd));

    while(1){
        chdir(cwd);

        printf("%s > ", cwd);

        gets(str);

        pid=vfork();

        if(pid == 0){
            num = 0;
            word[num] = strtok (str, " ");

            while (word[num] != NULL) {
                word[num] = strdup (word[num]);
                len = strlen (word[num]);
                if (strlen (word[num]) > 0)
                    if (word[num][len-1] == '\n')
                        word[num][len-1] = '\0';
                word[++num] = strtok (NULL, " ");
            }

            if(strcmp(word[0], "cd") == 0){
                chdir(word[1]);
                getcwd(cwd, sizeof(cwd));
            }
            else{
                execvp(word[0],word);
            }

            exit(0);
        }
        else{
            wait(&status);
        }
    }

    return 0;
}
4

1 回答 1

9

ls -l | less实际上是一个 shell 命令行,由通过管道连接的两个进程组成。该execvp()调用只能产生一个进程。

如果您想从程序中执行此操作,则必须显式调用 shell - 通过使用system()调用或将命令行更改为sh -c 'ls -l | less'. 您的word数组应如下所示:

word[0] = "sh"
word[1] = "-c"
word[2] = "ls -l | less"
word[3] = NULL

[编辑] 或者,您可以执行 shell 在内部执行的操作:生成两个进程并用管道连接它们。这将涉及使用fork()pipe()dup2()调用execve()。但是,调用 shell 的工作量要少得多,而且由于less它是一个交互式程序,因此您无需过多担心性能:任何花费不到 100 毫秒的东西都被认为是瞬时的。

于 2013-09-03T23:45:52.967 回答