Search code examples
c++operating-systemexecsystem-callsexecvp

Running 'grep' command using exec functions


I am trying to run grep command using execvp. I have to save the output into an output file like output.txt. The code, I have tried is given below:

#include<iostream>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
using namespace std;
int main(){
    pid_t pid = fork();
    int status = 0;
    char* args[] = {"grep", "-n", "out", "*", ">", "output.txt", NULL};
    //char* args[] = {"out", "/os_lab/assign_01/*", "/usr", NULL};
    if(pid == 0){
        cout<<"I am Child Process\n";
        status = 2;
        execvp("grep", args);
    }
    else if(pid > 0){
        cout<<"I am Parent Process\n";
        wait(&status);
    }   
    else{
        cout<<"Error in system call\n";
    }

    return 0;
}

When I run this code, the output on the terminal is as follows:

I am Parent Process
I am Child Process
grep: *: No such file or directory
grep: >: No such file or directory

Solution

  • The execvp() function calls directly the program and execute it with the provided arguments. The use of wildcards like * are provided by the shell terminal, so the grep is understanding the * as a file to be grep'ed.

    If you want to call the grap using wildcards and the operator > you should use the function system() on C++.

    The following code should work:

    #include<iostream>
    #include<unistd.h>
    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<sys/wait.h>
    using namespace std;
    int main(){
        pid_t pid = fork();
        int status = 0;
        //char* args[] = {"grep", "-n", "out", "*", ">", "output.txt", NULL};
    
        
        //char* args[] = {"out", "/os_lab/assign_01/*", "/usr", NULL};
        if(pid == 0){
            cout<<"I am Child Process\n";
            status = 2;
            //execvp("grep", args);
            system("grep -n out * > output.txt");
        }
        else if(pid > 0){
            cout<<"I am Parent Process\n";
            wait(&status);
        }   
        else{
            cout<<"Error in system call\n";
        }
    
        return 0;
    }