重定向 execvp 的 input/output

Redirecting input/output of execvp

我想在程序遇到“>”时将输出重定向到特定文件,并在找到“<”时从文件获取输入。

这适用于输入,但当我尝试将输出写入文件时,它不会在实际文件中写入任何内容,也不会在终端中显示。

我似乎无法弄清楚为什么,有人可以帮忙吗?

switch(fork()){
    case 0:

        for(i=0; i<num; i++){

            if(strcmp(argv[i], ">") == 0){
                if(fd1 = open(argv[i+1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR) < 0){
                    perror("cant open file");
                    exit(0);                    
                }
                dup2(fd1, 1);
                close(fd1);
                argv[i] = NULL;
            }

            if(strcmp(argv[i], "<") == 0){
                if(fd0 = open(argv[i+1], O_RDONLY) < 0){
                    perror("cant open file");
                    exit(0);                    
                }
                dup2(fd0, 0);
                close(fd0);
            }

        }

        execvp(argv[0], argv);

主要问题是 = 运算符的优先级低于 < 运算符。因此,在你的表达中

fd1 = open(argv[i+1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR) < 0

open() 的 return 值与 0 进行比较,然后将比较的结果(1 或 0)分配给 fd1。新打开的文件描述符丢失,不再使用。比较的实际结果很可能是 0(文件已成功打开),因此您的 dup2() 稍后调用几行尝试将文件描述符 0 复制到文件描述符 1 上。很可能有效,但任何尝试通过您执行的程序写入该文件描述符很可能会失败。

你应该写成

(fd1 = open(argv[i+1], O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) < 0

或者,不那么聪明,将其分成两个语句,这样一开始就不会出现优先级问题。

当你重定向输入时你有同样的问题,所以我怀疑你的说法 "This works for the input",但是因为在那种情况下你最终只会将文件描述符 0 复制到它自己上,问题将简单地表现为重定向未按预期工作——输入仍将来自原始程序的标准输入,而不是您指定的标准输入。

但是,如果您允许 shell 执行输入重定向而不是引用重定向运算符以便将其作为参数传递给程序,即使这样也可能不会引起注意。