简体   繁体   中英

Redirecting input/output of execvp

I want to redirect the output to a specific file when the program encounters a ">" and for it to get the input from a file if it finds a "<".

This works for the input, but when I try the output to file it doesn't write anything in the actual file nor does it show it in the terminal.

I can't seem to figure out why, can anyone help?

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);

The primary problem is that the = operator has lower precedence than the < operator. Thus, in your expression

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

, the return value of open() is compared to 0, and then the result of that comparison -- either 1 or 0 -- is assigned to fd1 . The newly-opened file descriptor is lost, and goes unused. The actual result of the comparison is most likely 0 (the file was successfully opened), so your dup2() call a few lines later attempts to dupe file descriptor 0 onto file descriptor 1. In all likelihood that works, but any attempt by the program you exec to write to that file descriptor very likely fails.

You ought to write it as

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

Alternatively, be a little less clever and separate that into two statements, so that the precedence question does not arise in the first place.

You have the same problem when you redirect input, so I'm doubtful of your claim that "This works for the input", but because in that case you'll end up just duping file descriptor 0 onto itself, the problem will manifest simply as the redirection not working as expected -- input will still come from the original program's standard input, not the standard input you designate.

Even that might go unnoticed, however, if you allow the shell to perform the input redirection instead of quoting the redirection operator so as to get it through to the program as an argument.

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