LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Execvp With Quotation Marks (https://www.linuxquestions.org/questions/programming-9/execvp-with-quotation-marks-385120/)

amitbern 11-21-2005 06:48 AM

Execvp With Quotation Marks
 
Hello,
I am trying to run a command using execvp
for example: execvp ("grep", arg_list);
but if one of the arguments is with the Quotation marks - for example grep "int main" test.c, or even grep "main" test.c
it doesnt run the command.
if i'm doing it through unix shell it works great.
any ideas?

Wim Sturkenboom 11-21-2005 10:10 AM

Code:

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

int main(int argc, char *argv[])
{

char *cmd[]={"grep","-n", "-H", "int main","execvp.c",NULL};

if(execvp("grep",cmd)<0)
{
  perror("execvp");
  return -1;
}

return 0;

When you save this as 'execvp.c', compile it and run it, it finds int main. It also gives the filenames and line numbers.
Why use quotation marks? Each argument that you pass in the arg_list is treated as a single argument.
If you try to combine -n and -H in one argument, grep will object.

amitbern 11-21-2005 12:28 PM

Quote:

Originally posted by Wim Sturkenboom
Code:

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

int main(int argc, char *argv[])
{

char *cmd[]={"grep","-n", "-H", "int main","execvp.c",NULL};

if(execvp("grep",cmd)<0)
{
  perror("execvp");
  return -1;
}

return 0;

When you save this as 'execvp.c', compile it and run it, it finds int main. It also gives the filenames and line numbers.
Why use quotation marks? Each argument that you pass in the arg_list is treated as a single argument.
If you try to combine -n and -H in one argument, grep will object.

I know all that but i need to find a way to use quotation marks through execvp.
i need to find the reason for not running with quotation marks.

Wim Sturkenboom 11-21-2005 02:15 PM

OK, I don't seem to understand the problem. I replaced the int main by a \" and it finds it perfectly (3 lines returned).

amitbern 11-21-2005 03:05 PM

your prog works just fine, try to run it with the real execvp() command...

execvp

Wim Sturkenboom 11-22-2005 01:36 AM

I'm lost. What do you mean by real execvp?

The above code was written using the man page that you gave.
Is it possible to post part of your code?

amitbern 11-24-2005 03:55 PM

This is a small Unix Shell
i can't seem to run the execvp() with the command - grep "main" test.c
compile the shell, and run the command: grep text textfile
and then : grep "text" textfile
it can't run with the quotation marks.
i don't know why...

Code:

#include  <stdio.h>
#include  <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <wait.h>

void  execute(char **argv,int background_flag)
{
        pid_t  pid;
        int    status;
        int j=0;
        int exe_process;

            if ((pid = fork()) < 0)      /* fork a child process          */
        {
                  printf("ERROR: forking child process failed\n");
                  exit(1);
            }
            else if (pid == 0)          /* for the child process:        */
        {
                printf("\033[42m\033[1m[%d]\033[m\033[m\n",getpid());
                if (execvp(*argv, argv)  < 0)      /* execute the command  */
                {
                              printf("ERROR: exec failed\n");
                              exit(1);
                }       
            }
            else                                            /* for the parent:      */
        {
                      if (background_flag==0) 
                {
                        while (wait(&status) != pid);
                        if (WIFEXITED (status))//WIFEXITED
                        {
                                printf("\033[45m\033[1m[%d]:  Done\033[m\033[m\n",pid);
                        }
                        else
                        {
                                printf ("the child process exited abnormally from signal %d\n",WTERMSIG(status ) );
                        }
                }


        }
}

int  main(void)
{
char  read_line[1024];
char* arg_list[10];
int i,background_flag,status;
pid_t pid;

while (1)
{                 
        i=0;
        background_flag=0;
//        printf("\033[44m\033[1m%s >\033[m\033[m",getenv("PWD"));   
        printf("\033[44m\033[1mUser_Shell:\033[m\033[m");       


        gets(read_line);           

        //clean zombie proccess
        if ((pid=waitpid(-1,&status,WNOHANG))!=-1)       
                printf("\033[45m\033[1m[%d]:  Done\033[m\033[m\n",pid);


        if (read_line[0]!=NULL)
{
        arg_list[i] = strtok(read_line," ");
        while (arg_list[i]!= NULL)
        {
                if (strcmp(arg_list[i],"&")) i++;
                else background_flag=1;
                arg_list[i]=strtok(NULL," """);
        }       


          if (strcmp(arg_list[0], "exit") == 0)
            exit(0); 

          execute(arg_list,background_flag);         
}

    }
return 0;
}


Wim Sturkenboom 11-25-2005 02:19 AM

I think that your problem is in the way you use strtok.
To parse a line, you have to call strtok more than once; the first time with read_line as argument
and consecutive calls with NULL instead of read_line.
The code below demonstrates how to use it.
Code:

int main()
{
char read_line[100], char *arg_list[10];
int cnt=0;

  strcpy(read_line,"hello, testing 1 2 3");

  arg_list[cnt]=strtok(read_line," ");
  while(arg_list[cnt]!=NULL)
  {
    printf("%s\n",arg_list[cnt]);
    arg_list[++cnt]=strtok(NULL," ");
  }

  return 0;
}

// edit:
please note that the use of strtok is not advised unless you know what
you're doing; the man-page states:
never use these functions

amitbern 11-25-2005 04:19 AM

Add this to your code, and try to run this:
1. grep text text_file - working
2. grep "text" text_file - Not working

Code:



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


int main()
{
char read_line[100];
char *arg_list[10];
int cnt=0;

gets(read_line);

arg_list[cnt]=strtok(read_line," ");

while(arg_list[cnt]!=NULL)
  {
    printf("%s\n",arg_list[cnt]);
    arg_list[++cnt]=strtok(NULL," ");
  }

execvp(arg_list[0], arg_list);

return 0;
}


Wim Sturkenboom 11-25-2005 07:42 AM

OK, finally see what you were trying to tell me.

When you add the quotes, it only finds the word if it's surrounded by quotes.
And that's slightly different from the grep behaviour on the commandline.

On the command line, you use the quotes to create one argument from words separated by spaces. So those
are not literal quotes.
The shell will read this and create one argument from it which will be passed to grep as you do in the code.
But the shell will strip off the quotes as it does not need it (it's just something for the shell).

In your program example, you literally look for a string including the quotes as you pass the quotes in the argument. On the
commandline this would be grep \"text\" text_file.

Hope this clears it. I think you have to do a bit more pre-processing before passing the string to execute.

amitbern 11-25-2005 10:28 AM

Thanks for your answer! it help a lot!


All times are GMT -5. The time now is 01:41 AM.