execvp()和/或字符串的问题,为什么这段代码不起作用?

时间:2017-05-16 18:15:47

标签: c linux shell exec strtok

我写了这段代码,打开一个文件并执行每行文件exept comment"#":

MYFILE:

ls -l
ls -a
cat /tmp/filex

代码:

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

void run(const char *cmd, const char *arg){
    char *argv[3];
    asprintf(&argv[0],"%s", cmd);
    asprintf(&argv[1], "%s", arg);
    argv[2] = NULL;
    pid_t pid = fork();
    if(pid == 0){
        execvp(argv[0], (char * const *) argv);
        perror("error: ");
        exit(EXIT_FAILURE);
    }
    waitpid(pid, NULL, 0);
}

void scriptexec(FILE *fp){
    char *line = NULL, *cmd = NULL, *arg=NULL, *delim=" \n\t";
    size_t len = 0;
    while(getline(&line, &len, fp) != -1){
        cmd = strtok_r(line, delim, &arg);
        if(cmd[0] != '#')
            run(cmd, arg);
    }
}

int main(int argc, char *argv[]){
    if(argc < 2) exit(EXIT_FAILURE);
    FILE *fp;
    if((fp = fopen(argv[1], "r" )) == NULL) exit(EXIT_FAILURE);
    scriptexec(fp);
    fclose(fp);
    return 0;
}

$ ./a.out文件

我得到了这个输出:

ls: invalid option -- '
'
Try 'ls --help' for more information.
ls: invalid option -- '
'
Try 'ls --help' for more information.
cat: /tmp/filex
: No such file or directory

我还尝试使用run()函数编写另一个代码,它工作正常,没问题!

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

void run(const char *cmd, const char *arg){
    char *argv[3];
    asprintf(&argv[0],"%s", cmd);
    asprintf(&argv[1], "%s", arg);
    argv[2] = NULL;
    pid_t pid = fork();
    if(pid == 0){
        execvp(argv[0], (char * const *) argv);
        perror("error: ");
        exit(EXIT_FAILURE);
    }
    waitpid(pid, NULL, 0);
}

int main(){
    run("ls", "-l");
}

我无法理解......

1 个答案:

答案 0 :(得分:2)

ls: invalid option -- '
'

查看两个单引号。有一个新行被传递给ls,这确实是一个“无效选项”。

getline()返回换行符,输入已用。

触发

只要把它剁掉,如果在周围,然后传递已阅读的东西。

为此,你可以使用:

line[strcspn(line, "\r\n")] = '\0';