简体   繁体   中英

Shell Commands in C (Error using Execvp)

I want to run the following command "ls | date" but whenever i isolate the ls and the date, they don't execute using execvp.

Problem:

Isolated:ls
ls: impossible to acess 'ld-linux-x86-64.so.2': Unknown directory or file
ls: impossible to acess 'ld-linux-x86-64.so.2': Unknown directory or file
Isolated: date
ls: impossible to acess 'date': Unknown directory or file

In the code, i want to check the ";" but when i check " " && "|" it isolates the parameters i want... but they don't run.

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

int main() {

 char command_line[256]="ls | date";
 char *ptr_current_command;
 char *saveptr1;
 char *saveptr2;
 char *saveptr3;
 char *ptr_current_parameter;
 char *ptr_current_parameter2;

 char *str[256];
 int i=0;
 int wait_child;
 pid_t pid;



    //Uses Strtok to recognize token ";"     
    ptr_current_command=strtok_r(command_line, ";", &saveptr1);
while (ptr_current_command != NULL) {
    //printf("current_command: %s\n", ptr_current_command);

    //Uses Strtok to recognize token " "
    ptr_current_parameter=strtok_r(ptr_current_command, " ", &saveptr2);
    while(ptr_current_parameter != NULL){
       //printf("\tcurrent_parameter: %s\n", ptr_current_parameter);

       //Uses Strtok to recognize token "|"
       ptr_current_parameter2=strtok_r(ptr_current_parameter, "|", &saveptr3);
       while(ptr_current_parameter2 != NULL){
           printf("\t\tIsolei: %s\n", ptr_current_parameter2);


            str[i]=ptr_current_parameter2;
            i++;           
           //Closes token by token until final NULL of "|"
           ptr_current_parameter2=strtok_r(NULL, "|", &saveptr3);
        }


       pid=fork();
    if (pid < 0) { perror("fork"); exit(errno); }
    if (pid == 0){
        execvp(str[0], str);
        perror("execvp"); exit(errno);
        }   
    if (wait_child)
        waitpid(pid, NULL, 0);      

       //Fecha Delimitador Espaço
       ptr_current_parameter=strtok_r(NULL, " ", &saveptr2);
         }


    //Closes token by token until final NULL of ";"         
    ptr_current_command=strtok_r(NULL, ";", &saveptr1);
    }

return 0;
}

Two issues here.

First, you aren't building str correctly. It has to contain a NULL pointer value after the last parameter, otherwise execvp won't know which option is the last.

Since str is uninitialized, the contents of any element beyond the ones you set in the inner are undefined. Attempting to read those elements (as execvp does) invokes undefined behavior .

After the inner loop, you need to set the current index to NULL .

The second issue is that you don't reset i to 0 when entering the inner loop. So even if the first command works, the second one won't because it keeps writing past the parameters for the first command.

Your inner loop should look like this after the fix:

   i = 0;   // reset i for each command
   while(ptr_current_parameter2 != NULL){
       printf("\t\tIsolei: %s\n", ptr_current_parameter2);


        str[i]=ptr_current_parameter2;
        i++;           
       //Closes token by token until final NULL of "|"
       ptr_current_parameter2=strtok_r(NULL, "|", &saveptr3);
    }
    str[i] = NULL;  // terminate the list

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM