Вопрос

I am trying to code a shell. But my shell doesn't execute the command - ls -l | less. I am using execvp. the code is given below.

#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;
}
Это было полезно?

Решение

ls -l | less is actually a shell command line that consists of two processes connected by a pipe. The execvp() call can only spawn a single process.

If you want to do this from your program, you must invoke the shell explicitly - either by using the system() call, or by changing the command line to sh -c 'ls -l | less'. Your word array should look like this:

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

[EDIT] Alternatively, you could do what the shell is doing internally: spawn two processes and connect them with a pipe. This would involve using the fork(), pipe(), dup2() and execve() calls. However, invoking the shell is much less work, and since less is an interactive program anyway, you don't need to worry about performance that much: anything that takes less than 100 ms is perceived as instantaneous.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top