C中的Shell命令(使用Execvp时出错)

时间:2017-01-10 13:02:50

标签: c linux shell

我想运行以下命令" ls |日期"但每当我隔离ls和日期时,他们都不会使用execvp执行。

问题:

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

在代码中,我想检查&#34 ;;"但当我检查" " &安培;&安培; " |"它隔离了我想要的参数......但它们不会运行。

#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;
}

1 个答案:

答案 0 :(得分:1)

这里有两个问题。

首先,您没有正确构建str。它必须在最后一个参数后包含NULL指针值,否则execvp将不知道哪个选项是最后一个。

由于str未初始化,因此未在内部设置的元素之外的任何元素的内容都是未定义的。尝试阅读这些元素(如execvp所做)会调用undefined behavior

在内部循环之后,您需要将当前索引设置为NULL

第二个问题是进入内循环时不会将i重置为0。因此,即使第一个命令有效,第二个命令也不会,因为它会继续写入第一个命令的参数。

修复后你的内部循环应如下所示:

   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